]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Added Cilk runtime library (libcilkrts) into GCC.
authorBalaji V. Iyer <balaji.v.iyer@intel.com>
Tue, 29 Oct 2013 18:37:47 +0000 (18:37 +0000)
committerBalaji V. Iyer <bviyer@gcc.gnu.org>
Tue, 29 Oct 2013 18:37:47 +0000 (11:37 -0700)
From-SVN: r204173

112 files changed:
ChangeLog
Makefile.def
Makefile.in
configure
configure.ac
libcilkrts/ChangeLog [new file with mode: 0644]
libcilkrts/Makefile.am [new file with mode: 0644]
libcilkrts/Makefile.in [new file with mode: 0644]
libcilkrts/README [new file with mode: 0644]
libcilkrts/aclocal.m4 [new file with mode: 0644]
libcilkrts/configure [new file with mode: 0644]
libcilkrts/configure.ac [new file with mode: 0644]
libcilkrts/configure.tgt [new file with mode: 0644]
libcilkrts/include/cilk/cilk.h [new file with mode: 0644]
libcilkrts/include/cilk/cilk_api.h [new file with mode: 0644]
libcilkrts/include/cilk/cilk_api_linux.h [new file with mode: 0644]
libcilkrts/include/cilk/cilk_stub.h [new file with mode: 0644]
libcilkrts/include/cilk/cilk_undocumented.h [new file with mode: 0644]
libcilkrts/include/cilk/common.h [new file with mode: 0644]
libcilkrts/include/cilk/holder.h [new file with mode: 0644]
libcilkrts/include/cilk/hyperobject_base.h [new file with mode: 0644]
libcilkrts/include/cilk/metaprogramming.h [new file with mode: 0644]
libcilkrts/include/cilk/reducer.h [new file with mode: 0644]
libcilkrts/include/cilk/reducer_file.h [new file with mode: 0644]
libcilkrts/include/cilk/reducer_list.h [new file with mode: 0644]
libcilkrts/include/cilk/reducer_max.h [new file with mode: 0644]
libcilkrts/include/cilk/reducer_min.h [new file with mode: 0644]
libcilkrts/include/cilk/reducer_min_max.h [new file with mode: 0644]
libcilkrts/include/cilk/reducer_opadd.h [new file with mode: 0644]
libcilkrts/include/cilk/reducer_opand.h [new file with mode: 0644]
libcilkrts/include/cilk/reducer_opmul.h [new file with mode: 0644]
libcilkrts/include/cilk/reducer_opor.h [new file with mode: 0644]
libcilkrts/include/cilk/reducer_opxor.h [new file with mode: 0644]
libcilkrts/include/cilk/reducer_ostream.h [new file with mode: 0644]
libcilkrts/include/cilk/reducer_string.h [new file with mode: 0644]
libcilkrts/include/cilktools/cilkscreen.h [new file with mode: 0644]
libcilkrts/include/cilktools/cilkview.h [new file with mode: 0644]
libcilkrts/include/cilktools/fake_mutex.h [new file with mode: 0644]
libcilkrts/include/cilktools/lock_guard.h [new file with mode: 0644]
libcilkrts/include/internal/abi.h [new file with mode: 0644]
libcilkrts/include/internal/cilk_fake.h [new file with mode: 0644]
libcilkrts/include/internal/cilk_version.h [new file with mode: 0644]
libcilkrts/include/internal/metacall.h [new file with mode: 0644]
libcilkrts/include/internal/rev.mk [new file with mode: 0644]
libcilkrts/mk/cilk-version.mk [new file with mode: 0644]
libcilkrts/runtime/acknowledgements.dox [new file with mode: 0644]
libcilkrts/runtime/bug.cpp [new file with mode: 0644]
libcilkrts/runtime/bug.h [new file with mode: 0644]
libcilkrts/runtime/c_reducers.c [new file with mode: 0644]
libcilkrts/runtime/cilk-abi-cilk-for.cpp [new file with mode: 0644]
libcilkrts/runtime/cilk-abi-vla-internal.c [new file with mode: 0644]
libcilkrts/runtime/cilk-abi-vla-internal.h [new file with mode: 0644]
libcilkrts/runtime/cilk-abi.c [new file with mode: 0644]
libcilkrts/runtime/cilk-ittnotify.h [new file with mode: 0644]
libcilkrts/runtime/cilk-tbb-interop.h [new file with mode: 0644]
libcilkrts/runtime/cilk_api.c [new file with mode: 0644]
libcilkrts/runtime/cilk_fiber-unix.cpp [new file with mode: 0644]
libcilkrts/runtime/cilk_fiber-unix.h [new file with mode: 0644]
libcilkrts/runtime/cilk_fiber.cpp [new file with mode: 0644]
libcilkrts/runtime/cilk_fiber.h [new file with mode: 0644]
libcilkrts/runtime/cilk_malloc.c [new file with mode: 0644]
libcilkrts/runtime/cilk_malloc.h [new file with mode: 0644]
libcilkrts/runtime/component.h [new file with mode: 0644]
libcilkrts/runtime/config/generic/cilk-abi-vla.c [new file with mode: 0644]
libcilkrts/runtime/config/generic/os-fence.h [new file with mode: 0644]
libcilkrts/runtime/config/generic/os-unix-sysdep.c [new file with mode: 0644]
libcilkrts/runtime/config/x86/cilk-abi-vla.c [new file with mode: 0644]
libcilkrts/runtime/config/x86/os-fence.h [new file with mode: 0644]
libcilkrts/runtime/config/x86/os-unix-sysdep.c [new file with mode: 0644]
libcilkrts/runtime/doxygen-layout.xml [new file with mode: 0644]
libcilkrts/runtime/doxygen.cfg [new file with mode: 0644]
libcilkrts/runtime/except-gcc.cpp [new file with mode: 0644]
libcilkrts/runtime/except-gcc.h [new file with mode: 0644]
libcilkrts/runtime/except.h [new file with mode: 0644]
libcilkrts/runtime/frame_malloc.c [new file with mode: 0644]
libcilkrts/runtime/frame_malloc.h [new file with mode: 0644]
libcilkrts/runtime/full_frame.c [new file with mode: 0644]
libcilkrts/runtime/full_frame.h [new file with mode: 0644]
libcilkrts/runtime/global_state.cpp [new file with mode: 0644]
libcilkrts/runtime/global_state.h [new file with mode: 0644]
libcilkrts/runtime/jmpbuf.c [new file with mode: 0644]
libcilkrts/runtime/jmpbuf.h [new file with mode: 0644]
libcilkrts/runtime/linux-symbols.ver [new file with mode: 0644]
libcilkrts/runtime/local_state.c [new file with mode: 0644]
libcilkrts/runtime/local_state.h [new file with mode: 0644]
libcilkrts/runtime/mac-symbols.txt [new file with mode: 0644]
libcilkrts/runtime/metacall_impl.c [new file with mode: 0644]
libcilkrts/runtime/metacall_impl.h [new file with mode: 0644]
libcilkrts/runtime/os-unix.c [new file with mode: 0644]
libcilkrts/runtime/os.h [new file with mode: 0644]
libcilkrts/runtime/os_mutex-unix.c [new file with mode: 0644]
libcilkrts/runtime/os_mutex.h [new file with mode: 0644]
libcilkrts/runtime/pedigrees.c [new file with mode: 0644]
libcilkrts/runtime/pedigrees.h [new file with mode: 0644]
libcilkrts/runtime/record-replay.cpp [new file with mode: 0644]
libcilkrts/runtime/record-replay.h [new file with mode: 0644]
libcilkrts/runtime/reducer_impl.cpp [new file with mode: 0644]
libcilkrts/runtime/reducer_impl.h [new file with mode: 0644]
libcilkrts/runtime/rts-common.h [new file with mode: 0644]
libcilkrts/runtime/scheduler.c [new file with mode: 0644]
libcilkrts/runtime/scheduler.h [new file with mode: 0644]
libcilkrts/runtime/signal_node.c [new file with mode: 0644]
libcilkrts/runtime/signal_node.h [new file with mode: 0644]
libcilkrts/runtime/spin_mutex.c [new file with mode: 0644]
libcilkrts/runtime/spin_mutex.h [new file with mode: 0644]
libcilkrts/runtime/stats.c [new file with mode: 0644]
libcilkrts/runtime/stats.h [new file with mode: 0644]
libcilkrts/runtime/symbol_test.c [new file with mode: 0644]
libcilkrts/runtime/sysdep-unix.c [new file with mode: 0644]
libcilkrts/runtime/sysdep.h [new file with mode: 0644]
libcilkrts/runtime/worker_mutex.c [new file with mode: 0644]
libcilkrts/runtime/worker_mutex.h [new file with mode: 0644]

index 2b27bce672643e2514b86f290c70b3c413b84691..f5563b2d3aa7e7578838100d28f9de1567f73bab 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2013-10-29  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       * Makefile.def: Add libcilkrts to target_modules.  Make libcilkrts 
+       depend on libstdc++ and libgcc.
+       * configure: Regenerate.
+       * configure.ac: Added libcilkrts to target binaries.  Also, restrict
+       libcilkrts for POSIX and i*86, and x86_64 architectures.
+       * Makefile.in: Added libcilkrts related fields to support building it.
+
 2013-10-26  Jeff Law  <law@redhat.com>
 
        * Makefile.def (target_modules): Remove libmudflap
index df4b2242e9670cb05bf245917daa04df45999204..32296d1160f8205177a405fbf91a67d2325ff8b7 100644 (file)
@@ -125,6 +125,8 @@ target_modules = { module= libvtv;
                   bootstrap=true;
                   lib_path=.libs;
                   raw_cxx=true; };
+target_modules = { module= libcilkrts;
+                  lib_path=.libs; };
 target_modules = { module= libssp; lib_path=.libs; };
 target_modules = { module= newlib; };
 target_modules = { module= libgcc; bootstrap=true; no_check=true; };
@@ -491,6 +493,7 @@ dependencies = { module=all-m4; on=all-build-texinfo; };
 // on libgcc and newlib/libgloss.
 lang_env_dependencies = { module=libjava; cxx=true; };
 lang_env_dependencies = { module=libitm; cxx=true; };
+lang_env_dependencies = { module=libcilkrts; cxx=true; };
 lang_env_dependencies = { module=newlib; no_c=true; };
 lang_env_dependencies = { module=libgloss; no_c=true; };
 lang_env_dependencies = { module=libgcc; no_gcc=true; no_c=true; };
@@ -531,6 +534,8 @@ dependencies = { module=install-target-libsanitizer; on=install-target-libstdc++
 dependencies = { module=install-target-libsanitizer; on=install-target-libgcc; };
 dependencies = { module=install-target-libvtv; on=install-target-libstdc++-v3; };
 dependencies = { module=install-target-libvtv; on=install-target-libgcc; };
+dependencies = { module=install-target-libcilkrts; on=install-target-libstdc++-v3; };
+dependencies = { module=install-target-libcilkrts; on=install-target-libgcc; };
 dependencies = { module=install-target-libjava; on=install-target-libgcc; };
 dependencies = { module=install-target-libitm; on=install-target-libgcc; };
 dependencies = { module=install-target-libobjc; on=install-target-libgcc; };
index ff434fed3151ef071e617f9fbce28eadfa365451..572b3d0941e425a5a334b8364ca3ad42dfc332a5 100644 (file)
@@ -575,7 +575,7 @@ all:
 
 # This is the list of directories that may be needed in RPATH_ENVVAR
 # so that programs built for the target machine work.
-TARGET_LIB_PATH = $(TARGET_LIB_PATH_libstdc++-v3)$(TARGET_LIB_PATH_libsanitizer)$(TARGET_LIB_PATH_libvtv)$(TARGET_LIB_PATH_libssp)$(TARGET_LIB_PATH_libgomp)$(TARGET_LIB_PATH_libitm)$(TARGET_LIB_PATH_libatomic)$(HOST_LIB_PATH_gcc)
+TARGET_LIB_PATH = $(TARGET_LIB_PATH_libstdc++-v3)$(TARGET_LIB_PATH_libsanitizer)$(TARGET_LIB_PATH_libvtv)$(TARGET_LIB_PATH_libssp)$(TARGET_LIB_PATH_libgomp)$(TARGET_LIB_PATH_libitm)$(TARGET_LIB_PATH_libatomic)$(HOST_LIB_PATH_gcc)$(HOST_LIB_PATH_libcilkrts)
 
 @if target-libstdc++-v3
 TARGET_LIB_PATH_libstdc++-v3 = $$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs:
@@ -597,6 +597,10 @@ TARGET_LIB_PATH_libssp = $$r/$(TARGET_SUBDIR)/libssp/.libs:
 TARGET_LIB_PATH_libgomp = $$r/$(TARGET_SUBDIR)/libgomp/.libs:
 @endif target-libgomp
 
+@if target-libcilkrts
+TARGET_LIB_PATH_libcilkrts = $$r/$(TARGET_SUBDIR)/libcilkrts/.libs:
+@endif target-libcilkrts
+
 @if target-libitm
 TARGET_LIB_PATH_libitm = $$r/$(TARGET_SUBDIR)/libitm/.libs:
 @endif target-libitm
@@ -942,6 +946,7 @@ configure-target:  \
     maybe-configure-target-boehm-gc \
     maybe-configure-target-rda \
     maybe-configure-target-libada \
+    maybe-configure-target-libcilkrts \
     maybe-configure-target-libgomp \
     maybe-configure-target-libitm \
     maybe-configure-target-libatomic
@@ -1100,6 +1105,7 @@ all-target: maybe-all-target-libada
 @if target-libgomp-no-bootstrap
 all-target: maybe-all-target-libgomp
 @endif target-libgomp-no-bootstrap
+all-target: maybe-all-target-libcilkrts
 all-target: maybe-all-target-libitm
 all-target: maybe-all-target-libatomic
 
@@ -1925,6 +1931,7 @@ mostlyclean-target: maybe-mostlyclean-target-boehm-gc
 mostlyclean-target: maybe-mostlyclean-target-rda
 mostlyclean-target: maybe-mostlyclean-target-libada
 mostlyclean-target: maybe-mostlyclean-target-libgomp
+mostlyclean-target: maybe-mostlyclean-target-libcilkrts
 mostlyclean-target: maybe-mostlyclean-target-libitm
 mostlyclean-target: maybe-mostlyclean-target-libatomic
 
@@ -2007,6 +2014,7 @@ clean-target: maybe-clean-target-boehm-gc
 clean-target: maybe-clean-target-rda
 clean-target: maybe-clean-target-libada
 clean-target: maybe-clean-target-libgomp
+clean-target: maybe-clean-target-libcilkrts
 clean-target: maybe-clean-target-libitm
 clean-target: maybe-clean-target-libatomic
 
@@ -2089,6 +2097,7 @@ distclean-target: maybe-distclean-target-boehm-gc
 distclean-target: maybe-distclean-target-rda
 distclean-target: maybe-distclean-target-libada
 distclean-target: maybe-distclean-target-libgomp
+distclean-target: maybe-distclean-target-libcilkrts
 distclean-target: maybe-distclean-target-libitm
 distclean-target: maybe-distclean-target-libatomic
 
@@ -2171,6 +2180,7 @@ maintainer-clean-target: maybe-maintainer-clean-target-boehm-gc
 maintainer-clean-target: maybe-maintainer-clean-target-rda
 maintainer-clean-target: maybe-maintainer-clean-target-libada
 maintainer-clean-target: maybe-maintainer-clean-target-libgomp
+maintainer-clean-target: maybe-maintainer-clean-target-libcilkrts
 maintainer-clean-target: maybe-maintainer-clean-target-libitm
 maintainer-clean-target: maybe-maintainer-clean-target-libatomic
 
@@ -2463,6 +2473,7 @@ install-target:  \
     maybe-install-target-rda \
     maybe-install-target-libada \
     maybe-install-target-libgomp \
+    maybe-install-target-libcilkrts \
     maybe-install-target-libitm \
     maybe-install-target-libatomic
 
@@ -2564,6 +2575,7 @@ install-strip-target:  \
     maybe-install-strip-target-boehm-gc \
     maybe-install-strip-target-rda \
     maybe-install-strip-target-libada \
+    maybe-install-strip-target-libcilkrts \
     maybe-install-strip-target-libgomp \
     maybe-install-strip-target-libitm \
     maybe-install-strip-target-libatomic
@@ -41869,6 +41881,983 @@ maintainer-clean-target-libada:
 @endif target-libada
 
 
+.PHONY: configure-target-libcilkrts maybe-configure-target-libcilkrts
+maybe-configure-target-libcilkrts:
+@if gcc-bootstrap
+configure-target-libcilkrts: stage_current
+@endif gcc-bootstrap
+@if target-libcilkrts
+maybe-configure-target-libcilkrts: configure-target-libcilkrts
+configure-target-libcilkrts: 
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       echo "Checking multilib configuration for libcilkrts...(1)"; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts ; \
+       $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libcilkrts/multilib.tmp 2> /dev/null ; \
+       if test -r $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+         if cmp -s $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/multilib.tmp; \
+         else \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/Makefile; \
+           mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+         fi; \
+       else \
+         mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+       fi; \
+       test ! -f $(TARGET_SUBDIR)/libcilkrts/Makefile || exit 0; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts ; \
+       $(NORMAL_TARGET_EXPORTS)  \
+       echo Configuring in $(TARGET_SUBDIR)/libcilkrts; \
+       cd "$(TARGET_SUBDIR)/libcilkrts" || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(TARGET_SUBDIR)/libcilkrts/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/libcilkrts"; \
+       libsrcdir="$$s/libcilkrts"; \
+       rm -f no-such-file || : ; \
+       CONFIG_SITE=no-such-file $(SHELL) $${libsrcdir}/configure \
+         $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+         --target=${target_alias} $${srcdiroption}  \
+         || exit 1 
+@endif target-libcilkrts
+
+
+.PHONY: configure-stage1-target-libcilkrts maybe-configure-stage1-target-libcilkrts
+maybe-configure-stage1-target-libcilkrts:
+@if target-libcilkrts-bootstrap
+maybe-configure-stage1-target-libcilkrts: configure-stage1-target-libcilkrts
+configure-stage1-target-libcilkrts:
+       @[ $(current_stage) = stage1 ] || $(MAKE) stage1-start
+       @$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE1_TFLAGS)"; \
+       echo "Checking multilib configuration for libcilkrts...(2)"; \
+       $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libcilkrts/multilib.tmp 2> /dev/null ; \
+       if test -r $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+         if cmp -s $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/multilib.tmp; \
+         else \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/Makefile; \
+           mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+         fi; \
+       else \
+         mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+       fi; \
+       test ! -f $(TARGET_SUBDIR)/libcilkrts/Makefile || exit 0; \
+       $(NORMAL_TARGET_EXPORTS) \
+       CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+       CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+       LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)"; export LIBCFLAGS;  \
+       echo Configuring stage 1 in $(TARGET_SUBDIR)/libcilkrts ; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts ; \
+       cd $(TARGET_SUBDIR)/libcilkrts || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(TARGET_SUBDIR)/libcilkrts/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/libcilkrts"; \
+       libsrcdir="$$s/libcilkrts"; \
+       $(SHELL) $${libsrcdir}/configure \
+         $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+         --target=${target_alias} $${srcdiroption} \
+         $(STAGE1_CONFIGURE_FLAGS)
+@endif target-libcilkrts-bootstrap
+
+.PHONY: configure-stage2-target-libcilkrts maybe-configure-stage2-target-libcilkrts
+maybe-configure-stage2-target-libcilkrts:
+@if target-libcilkrts-bootstrap
+maybe-configure-stage2-target-libcilkrts: configure-stage2-target-libcilkrts
+configure-stage2-target-libcilkrts:
+       @[ $(current_stage) = stage2 ] || $(MAKE) stage2-start
+       @$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE2_TFLAGS)"; \
+       echo "Checking multilib configuration for libcilkrts...(3)"; \
+       $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libcilkrts/multilib.tmp 2> /dev/null ; \
+       if test -r $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+         if cmp -s $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/multilib.tmp; \
+         else \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/Makefile; \
+           mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+         fi; \
+       else \
+         mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+       fi; \
+       test ! -f $(TARGET_SUBDIR)/libcilkrts/Makefile || exit 0; \
+       $(NORMAL_TARGET_EXPORTS) \
+        \
+       CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+       CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+       LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)"; export LIBCFLAGS;  \
+       echo Configuring stage 2 in $(TARGET_SUBDIR)/libcilkrts ; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts ; \
+       cd $(TARGET_SUBDIR)/libcilkrts || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(TARGET_SUBDIR)/libcilkrts/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/libcilkrts"; \
+       libsrcdir="$$s/libcilkrts"; \
+       $(SHELL) $${libsrcdir}/configure \
+         $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+         --target=${target_alias} $${srcdiroption} \
+         --with-build-libsubdir=$(HOST_SUBDIR) \
+         $(STAGE2_CONFIGURE_FLAGS)
+@endif target-libcilkrts-bootstrap
+
+.PHONY: configure-stage3-target-libcilkrts maybe-configure-stage3-target-libcilkrts
+maybe-configure-stage3-target-libcilkrts:
+@if target-libcilkrts-bootstrap
+maybe-configure-stage3-target-libcilkrts: configure-stage3-target-libcilkrts
+configure-stage3-target-libcilkrts:
+       @[ $(current_stage) = stage3 ] || $(MAKE) stage3-start
+       @$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE3_TFLAGS)"; \
+       echo "Checking multilib configuration for libcilkrts...(4)"; \
+       $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libcilkrts/multilib.tmp 2> /dev/null ; \
+       if test -r $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+         if cmp -s $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/multilib.tmp; \
+         else \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/Makefile; \
+           mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+         fi; \
+       else \
+         mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+       fi; \
+       test ! -f $(TARGET_SUBDIR)/libcilkrts/Makefile || exit 0; \
+       $(NORMAL_TARGET_EXPORTS) \
+        \
+       CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+       CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+       LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)"; export LIBCFLAGS;  \
+       echo Configuring stage 3 in $(TARGET_SUBDIR)/libcilkrts ; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts ; \
+       cd $(TARGET_SUBDIR)/libcilkrts || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(TARGET_SUBDIR)/libcilkrts/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/libcilkrts"; \
+       libsrcdir="$$s/libcilkrts"; \
+       $(SHELL) $${libsrcdir}/configure \
+         $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+         --target=${target_alias} $${srcdiroption} \
+         --with-build-libsubdir=$(HOST_SUBDIR) \
+         $(STAGE3_CONFIGURE_FLAGS)
+@endif target-libcilkrts-bootstrap
+
+.PHONY: configure-stage4-target-libcilkrts maybe-configure-stage4-target-libcilkrts
+maybe-configure-stage4-target-libcilkrts:
+@if target-libcilkrts-bootstrap
+maybe-configure-stage4-target-libcilkrts: configure-stage4-target-libcilkrts
+configure-stage4-target-libcilkrts:
+       @[ $(current_stage) = stage4 ] || $(MAKE) stage4-start
+       @$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE4_TFLAGS)"; \
+       echo "Checking multilib configuration for libcilkrts...(4)"; \
+       $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libcilkrts/multilib.tmp 2> /dev/null ; \
+       if test -r $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+         if cmp -s $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/multilib.tmp; \
+         else \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/Makefile; \
+           mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+         fi; \
+       else \
+         mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+       fi; \
+       test ! -f $(TARGET_SUBDIR)/libcilkrts/Makefile || exit 0; \
+       $(NORMAL_TARGET_EXPORTS) \
+        \
+       CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+       CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+       LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)"; export LIBCFLAGS;  \
+       echo Configuring stage 4 in $(TARGET_SUBDIR)/libcilkrts ; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts ; \
+       cd $(TARGET_SUBDIR)/libcilkrts || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(TARGET_SUBDIR)/libcilkrts/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/libcilkrts"; \
+       libsrcdir="$$s/libcilkrts"; \
+       $(SHELL) $${libsrcdir}/configure \
+         $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+         --target=${target_alias} $${srcdiroption} \
+         --with-build-libsubdir=$(HOST_SUBDIR) \
+         $(STAGE4_CONFIGURE_FLAGS)
+@endif target-libcilkrts-bootstrap
+
+.PHONY: configure-stageprofile-target-libcilkrts maybe-configure-stageprofile-target-libcilkrts
+maybe-configure-stageprofile-target-libcilkrts:
+@if target-libcilkrts-bootstrap
+maybe-configure-stageprofile-target-libcilkrts: configure-stageprofile-target-libcilkrts
+configure-stageprofile-target-libcilkrts:
+       @[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start
+       @$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGEprofile_TFLAGS)"; \
+       echo "Checking multilib configuration for libcilkrts...(5)"; \
+       $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libcilkrts/multilib.tmp 2> /dev/null ; \
+       if test -r $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+         if cmp -s $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/multilib.tmp; \
+         else \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/Makefile; \
+           mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+         fi; \
+       else \
+         mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+       fi; \
+       test ! -f $(TARGET_SUBDIR)/libcilkrts/Makefile || exit 0; \
+       $(NORMAL_TARGET_EXPORTS) \
+        \
+       CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+       CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+       LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)"; export LIBCFLAGS;  \
+       echo Configuring stage profile in $(TARGET_SUBDIR)/libcilkrts ; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts ; \
+       cd $(TARGET_SUBDIR)/libcilkrts || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(TARGET_SUBDIR)/libcilkrts/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/libcilkrts"; \
+       libsrcdir="$$s/libcilkrts"; \
+       $(SHELL) $${libsrcdir}/configure \
+         $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+         --target=${target_alias} $${srcdiroption} \
+         --with-build-libsubdir=$(HOST_SUBDIR) \
+         $(STAGEprofile_CONFIGURE_FLAGS)
+@endif target-libcilkrts-bootstrap
+
+.PHONY: configure-stagefeedback-target-libcilkrts maybe-configure-stagefeedback-target-libcilkrts
+maybe-configure-stagefeedback-target-libcilkrts:
+@if target-libcilkrts-bootstrap
+maybe-configure-stagefeedback-target-libcilkrts: configure-stagefeedback-target-libcilkrts
+configure-stagefeedback-target-libcilkrts:
+       @[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start
+       @$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGEfeedback_TFLAGS)"; \
+       echo "Checking multilib configuration for libcilkrts...(6)"; \
+       $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libcilkrts/multilib.tmp 2> /dev/null ; \
+       if test -r $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+         if cmp -s $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; then \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/multilib.tmp; \
+         else \
+           rm -f $(TARGET_SUBDIR)/libcilkrts/Makefile; \
+           mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+         fi; \
+       else \
+         mv $(TARGET_SUBDIR)/libcilkrts/multilib.tmp $(TARGET_SUBDIR)/libcilkrts/multilib.out; \
+       fi; \
+       test ! -f $(TARGET_SUBDIR)/libcilkrts/Makefile || exit 0; \
+       $(NORMAL_TARGET_EXPORTS) \
+        \
+       CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+       CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+       LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)"; export LIBCFLAGS;  \
+       echo Configuring stage feedback in $(TARGET_SUBDIR)/libcilkrts ; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libcilkrts ; \
+       cd $(TARGET_SUBDIR)/libcilkrts || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(TARGET_SUBDIR)/libcilkrts/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/libcilkrts"; \
+       libsrcdir="$$s/libcilkrts"; \
+       $(SHELL) $${libsrcdir}/configure \
+         $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+         --target=${target_alias} $${srcdiroption} \
+         --with-build-libsubdir=$(HOST_SUBDIR) \
+         $(STAGEfeedback_CONFIGURE_FLAGS)
+@endif target-libcilkrts-bootstrap
+
+
+
+
+
+.PHONY: all-target-libcilkrts maybe-all-target-libcilkrts
+maybe-all-target-libcilkrts:
+@if gcc-bootstrap
+all-target-libcilkrts: stage_current
+@endif gcc-bootstrap
+@if target-libcilkrts
+TARGET-target-libcilkrts=all
+maybe-all-target-libcilkrts: all-target-libcilkrts
+all-target-libcilkrts: configure-target-libcilkrts
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS)  \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) $(EXTRA_TARGET_FLAGS)  \
+               $(TARGET-target-libcilkrts))
+@endif target-libcilkrts
+
+
+
+.PHONY: all-stage1-target-libcilkrts maybe-all-stage1-target-libcilkrts
+.PHONY: clean-stage1-target-libcilkrts maybe-clean-stage1-target-libcilkrts
+maybe-all-stage1-target-libcilkrts:
+maybe-clean-stage1-target-libcilkrts:
+@if target-libcilkrts-bootstrap
+maybe-all-stage1-target-libcilkrts: all-stage1-target-libcilkrts
+all-stage1: all-stage1-target-libcilkrts
+TARGET-stage1-target-libcilkrts = $(TARGET-target-libcilkrts)
+all-stage1-target-libcilkrts: configure-stage1-target-libcilkrts
+       @[ $(current_stage) = stage1 ] || $(MAKE) stage1-start
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE1_TFLAGS)"; \
+       $(NORMAL_TARGET_EXPORTS)  \
+       cd $(TARGET_SUBDIR)/libcilkrts && \
+       $(MAKE) $(BASE_FLAGS_TO_PASS) \
+               CFLAGS="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)" \
+               CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+               $(EXTRA_TARGET_FLAGS)   \
+               TFLAGS="$(STAGE1_TFLAGS)" \
+               $(TARGET-stage1-target-libcilkrts)
+
+maybe-clean-stage1-target-libcilkrts: clean-stage1-target-libcilkrts
+clean-stage1: clean-stage1-target-libcilkrts
+clean-stage1-target-libcilkrts:
+       @if [ $(current_stage) = stage1 ]; then \
+         [ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0; \
+       else \
+         [ -f $(TARGET_SUBDIR)/stage1-libcilkrts/Makefile ] || exit 0; \
+         $(MAKE) stage1-start; \
+       fi; \
+       cd $(TARGET_SUBDIR)/libcilkrts && \
+       $(MAKE) $(EXTRA_TARGET_FLAGS)  \
+                clean
+@endif target-libcilkrts-bootstrap
+
+
+.PHONY: all-stage2-target-libcilkrts maybe-all-stage2-target-libcilkrts
+.PHONY: clean-stage2-target-libcilkrts maybe-clean-stage2-target-libcilkrts
+maybe-all-stage2-target-libcilkrts:
+maybe-clean-stage2-target-libcilkrts:
+@if target-libcilkrts-bootstrap
+maybe-all-stage2-target-libcilkrts: all-stage2-target-libcilkrts
+all-stage2: all-stage2-target-libcilkrts
+TARGET-stage2-target-libcilkrts = $(TARGET-target-libcilkrts)
+all-stage2-target-libcilkrts: configure-stage2-target-libcilkrts
+       @[ $(current_stage) = stage2 ] || $(MAKE) stage2-start
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE2_TFLAGS)"; \
+       $(NORMAL_TARGET_EXPORTS) \
+         \
+       cd $(TARGET_SUBDIR)/libcilkrts && \
+       $(MAKE) $(BASE_FLAGS_TO_PASS) \
+               CFLAGS="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)" \
+               CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+               $(EXTRA_TARGET_FLAGS)   \
+               TFLAGS="$(STAGE2_TFLAGS)" \
+               $(TARGET-stage2-target-libcilkrts)
+
+maybe-clean-stage2-target-libcilkrts: clean-stage2-target-libcilkrts
+clean-stage2: clean-stage2-target-libcilkrts
+clean-stage2-target-libcilkrts:
+       @if [ $(current_stage) = stage2 ]; then \
+         [ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0; \
+       else \
+         [ -f $(TARGET_SUBDIR)/stage2-libcilkrts/Makefile ] || exit 0; \
+         $(MAKE) stage2-start; \
+       fi; \
+       cd $(TARGET_SUBDIR)/libcilkrts && \
+       $(MAKE) $(EXTRA_TARGET_FLAGS)  \
+                 \
+                clean
+@endif target-libcilkrts-bootstrap
+
+
+.PHONY: all-stage3-target-libcilkrts maybe-all-stage3-target-libcilkrts
+.PHONY: clean-stage3-target-libcilkrts maybe-clean-stage3-target-libcilkrts
+maybe-all-stage3-target-libcilkrts:
+maybe-clean-stage3-target-libcilkrts:
+@if target-libcilkrts-bootstrap
+maybe-all-stage3-target-libcilkrts: all-stage3-target-libcilkrts
+all-stage3: all-stage3-target-libcilkrts
+TARGET-stage3-target-libcilkrts = $(TARGET-target-libcilkrts)
+all-stage3-target-libcilkrts: configure-stage3-target-libcilkrts
+       @[ $(current_stage) = stage3 ] || $(MAKE) stage3-start
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE3_TFLAGS)"; \
+       $(NORMAL_TARGET_EXPORTS) \
+         \
+       cd $(TARGET_SUBDIR)/libcilkrts && \
+       $(MAKE) $(BASE_FLAGS_TO_PASS) \
+               CFLAGS="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)" \
+               CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+               $(EXTRA_TARGET_FLAGS)   \
+               TFLAGS="$(STAGE3_TFLAGS)" \
+               $(TARGET-stage3-target-libcilkrts)
+
+maybe-clean-stage3-target-libcilkrts: clean-stage3-target-libcilkrts
+clean-stage3: clean-stage3-target-libcilkrts
+clean-stage3-target-libcilkrts:
+       @if [ $(current_stage) = stage3 ]; then \
+         [ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0; \
+       else \
+         [ -f $(TARGET_SUBDIR)/stage3-libcilkrts/Makefile ] || exit 0; \
+         $(MAKE) stage3-start; \
+       fi; \
+       cd $(TARGET_SUBDIR)/libcilkrts && \
+       $(MAKE) $(EXTRA_TARGET_FLAGS)  \
+                 \
+                clean
+@endif target-libcilkrts-bootstrap
+
+
+.PHONY: all-stage4-target-libcilkrts maybe-all-stage4-target-libcilkrts
+.PHONY: clean-stage4-target-libcilkrts maybe-clean-stage4-target-libcilkrts
+maybe-all-stage4-target-libcilkrts:
+maybe-clean-stage4-target-libcilkrts:
+@if target-libcilkrts-bootstrap
+maybe-all-stage4-target-libcilkrts: all-stage4-target-libcilkrts
+all-stage4: all-stage4-target-libcilkrts
+TARGET-stage4-target-libcilkrts = $(TARGET-target-libcilkrts)
+all-stage4-target-libcilkrts: configure-stage4-target-libcilkrts
+       @[ $(current_stage) = stage4 ] || $(MAKE) stage4-start
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE4_TFLAGS)"; \
+       $(NORMAL_TARGET_EXPORTS) \
+         \
+       cd $(TARGET_SUBDIR)/libcilkrts && \
+       $(MAKE) $(BASE_FLAGS_TO_PASS) \
+               CFLAGS="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)" \
+               CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+               $(EXTRA_TARGET_FLAGS)   \
+               TFLAGS="$(STAGE4_TFLAGS)" \
+               $(TARGET-stage4-target-libcilkrts)
+
+maybe-clean-stage4-target-libcilkrts: clean-stage4-target-libcilkrts
+clean-stage4: clean-stage4-target-libcilkrts
+clean-stage4-target-libcilkrts:
+       @if [ $(current_stage) = stage4 ]; then \
+         [ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0; \
+       else \
+         [ -f $(TARGET_SUBDIR)/stage4-libcilkrts/Makefile ] || exit 0; \
+         $(MAKE) stage4-start; \
+       fi; \
+       cd $(TARGET_SUBDIR)/libcilkrts && \
+       $(MAKE) $(EXTRA_TARGET_FLAGS)  \
+                 \
+                clean
+@endif target-libcilkrts-bootstrap
+
+
+.PHONY: all-stageprofile-target-libcilkrts maybe-all-stageprofile-target-libcilkrts
+.PHONY: clean-stageprofile-target-libcilkrts maybe-clean-stageprofile-target-libcilkrts
+maybe-all-stageprofile-target-libcilkrts:
+maybe-clean-stageprofile-target-libcilkrts:
+@if target-libcilkrts-bootstrap
+maybe-all-stageprofile-target-libcilkrts: all-stageprofile-target-libcilkrts
+all-stageprofile: all-stageprofile-target-libcilkrts
+TARGET-stageprofile-target-libcilkrts = $(TARGET-target-libcilkrts)
+all-stageprofile-target-libcilkrts: configure-stageprofile-target-libcilkrts
+       @[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGEprofile_TFLAGS)"; \
+       $(NORMAL_TARGET_EXPORTS) \
+         \
+       cd $(TARGET_SUBDIR)/libcilkrts && \
+       $(MAKE) $(BASE_FLAGS_TO_PASS) \
+               CFLAGS="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)" \
+               CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+               $(EXTRA_TARGET_FLAGS)   \
+               TFLAGS="$(STAGEprofile_TFLAGS)" \
+               $(TARGET-stageprofile-target-libcilkrts)
+
+maybe-clean-stageprofile-target-libcilkrts: clean-stageprofile-target-libcilkrts
+clean-stageprofile: clean-stageprofile-target-libcilkrts
+clean-stageprofile-target-libcilkrts:
+       @if [ $(current_stage) = stageprofile ]; then \
+         [ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0; \
+       else \
+         [ -f $(TARGET_SUBDIR)/stageprofile-libcilkrts/Makefile ] || exit 0; \
+         $(MAKE) stageprofile-start; \
+       fi; \
+       cd $(TARGET_SUBDIR)/libcilkrts && \
+       $(MAKE) $(EXTRA_TARGET_FLAGS)  \
+                 \
+                clean
+@endif target-libcilkrts-bootstrap
+
+
+.PHONY: all-stagefeedback-target-libcilkrts maybe-all-stagefeedback-target-libcilkrts
+.PHONY: clean-stagefeedback-target-libcilkrts maybe-clean-stagefeedback-target-libcilkrts
+maybe-all-stagefeedback-target-libcilkrts:
+maybe-clean-stagefeedback-target-libcilkrts:
+@if target-libcilkrts-bootstrap
+maybe-all-stagefeedback-target-libcilkrts: all-stagefeedback-target-libcilkrts
+all-stagefeedback: all-stagefeedback-target-libcilkrts
+TARGET-stagefeedback-target-libcilkrts = $(TARGET-target-libcilkrts)
+all-stagefeedback-target-libcilkrts: configure-stagefeedback-target-libcilkrts
+       @[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGEfeedback_TFLAGS)"; \
+       $(NORMAL_TARGET_EXPORTS) \
+         \
+       cd $(TARGET_SUBDIR)/libcilkrts && \
+       $(MAKE) $(BASE_FLAGS_TO_PASS) \
+               CFLAGS="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)" \
+               CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+               $(EXTRA_TARGET_FLAGS)   \
+               TFLAGS="$(STAGEfeedback_TFLAGS)" \
+               $(TARGET-stagefeedback-target-libcilkrts)
+
+maybe-clean-stagefeedback-target-libcilkrts: clean-stagefeedback-target-libcilkrts
+clean-stagefeedback: clean-stagefeedback-target-libcilkrts
+clean-stagefeedback-target-libcilkrts:
+       @if [ $(current_stage) = stagefeedback ]; then \
+         [ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0; \
+       else \
+         [ -f $(TARGET_SUBDIR)/stagefeedback-libcilkrts/Makefile ] || exit 0; \
+         $(MAKE) stagefeedback-start; \
+       fi; \
+       cd $(TARGET_SUBDIR)/libcilkrts && \
+       $(MAKE) $(EXTRA_TARGET_FLAGS)  \
+                 \
+                clean
+@endif target-libcilkrts-bootstrap
+
+
+
+
+
+
+.PHONY: check-target-libcilkrts maybe-check-target-libcilkrts
+maybe-check-target-libcilkrts:
+@if target-libcilkrts
+maybe-check-target-libcilkrts: check-target-libcilkrts
+
+check-target-libcilkrts:
+       @: $(MAKE); $(unstage)
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(TARGET_FLAGS_TO_PASS)   check)
+
+@endif target-libcilkrts
+
+.PHONY: install-target-libcilkrts maybe-install-target-libcilkrts
+maybe-install-target-libcilkrts:
+@if target-libcilkrts
+maybe-install-target-libcilkrts: install-target-libcilkrts
+
+install-target-libcilkrts: installdirs
+       @: $(MAKE); $(unstage)
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(TARGET_FLAGS_TO_PASS)  install)
+
+@endif target-libcilkrts
+
+.PHONY: install-strip-target-libcilkrts maybe-install-strip-target-libcilkrts
+maybe-install-strip-target-libcilkrts:
+@if target-libcilkrts
+maybe-install-strip-target-libcilkrts: install-strip-target-libcilkrts
+
+install-strip-target-libcilkrts: installdirs
+       @: $(MAKE); $(unstage)
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(TARGET_FLAGS_TO_PASS)  install-strip)
+
+@endif target-libcilkrts
+
+# Other targets (info, dvi, pdf, etc.)
+
+.PHONY: maybe-info-target-libcilkrts info-target-libcilkrts
+maybe-info-target-libcilkrts:
+@if target-libcilkrts
+maybe-info-target-libcilkrts: info-target-libcilkrts
+
+info-target-libcilkrts: \
+    configure-target-libcilkrts 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing info in $(TARGET_SUBDIR)/libcilkrts" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                  info) \
+         || exit 1
+
+@endif target-libcilkrts
+
+.PHONY: maybe-dvi-target-libcilkrts dvi-target-libcilkrts
+maybe-dvi-target-libcilkrts:
+@if target-libcilkrts
+maybe-dvi-target-libcilkrts: dvi-target-libcilkrts
+
+dvi-target-libcilkrts: \
+    configure-target-libcilkrts 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing dvi in $(TARGET_SUBDIR)/libcilkrts" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                  dvi) \
+         || exit 1
+
+@endif target-libcilkrts
+
+.PHONY: maybe-pdf-target-libcilkrts pdf-target-libcilkrts
+maybe-pdf-target-libcilkrts:
+@if target-libcilkrts
+maybe-pdf-target-libcilkrts: pdf-target-libcilkrts
+
+pdf-target-libcilkrts: \
+    configure-target-libcilkrts 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing pdf in $(TARGET_SUBDIR)/libcilkrts" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                  pdf) \
+         || exit 1
+
+@endif target-libcilkrts
+
+.PHONY: maybe-html-target-libcilkrts html-target-libcilkrts
+maybe-html-target-libcilkrts:
+@if target-libcilkrts
+maybe-html-target-libcilkrts: html-target-libcilkrts
+
+html-target-libcilkrts: \
+    configure-target-libcilkrts 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing html in $(TARGET_SUBDIR)/libcilkrts" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                  html) \
+         || exit 1
+
+@endif target-libcilkrts
+
+.PHONY: maybe-TAGS-target-libcilkrts TAGS-target-libcilkrts
+maybe-TAGS-target-libcilkrts:
+@if target-libcilkrts
+maybe-TAGS-target-libcilkrts: TAGS-target-libcilkrts
+
+TAGS-target-libcilkrts: \
+    configure-target-libcilkrts 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing TAGS in $(TARGET_SUBDIR)/libcilkrts" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                  TAGS) \
+         || exit 1
+
+@endif target-libcilkrts
+
+.PHONY: maybe-install-info-target-libcilkrts install-info-target-libcilkrts
+maybe-install-info-target-libcilkrts:
+@if target-libcilkrts
+maybe-install-info-target-libcilkrts: install-info-target-libcilkrts
+
+install-info-target-libcilkrts: \
+    configure-target-libcilkrts \
+    info-target-libcilkrts 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing install-info in $(TARGET_SUBDIR)/libcilkrts" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                  install-info) \
+         || exit 1
+
+@endif target-libcilkrts
+
+.PHONY: maybe-install-pdf-target-libcilkrts install-pdf-target-libcilkrts
+maybe-install-pdf-target-libcilkrts:
+@if target-libcilkrts
+maybe-install-pdf-target-libcilkrts: install-pdf-target-libcilkrts
+
+install-pdf-target-libcilkrts: \
+    configure-target-libcilkrts \
+    pdf-target-libcilkrts 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing install-pdf in $(TARGET_SUBDIR)/libcilkrts" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                  install-pdf) \
+         || exit 1
+
+@endif target-libcilkrts
+
+.PHONY: maybe-install-html-target-libcilkrts install-html-target-libcilkrts
+maybe-install-html-target-libcilkrts:
+@if target-libcilkrts
+maybe-install-html-target-libcilkrts: install-html-target-libcilkrts
+
+install-html-target-libcilkrts: \
+    configure-target-libcilkrts \
+    html-target-libcilkrts 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing install-html in $(TARGET_SUBDIR)/libcilkrts" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                  install-html) \
+         || exit 1
+
+@endif target-libcilkrts
+
+.PHONY: maybe-installcheck-target-libcilkrts installcheck-target-libcilkrts
+maybe-installcheck-target-libcilkrts:
+@if target-libcilkrts
+maybe-installcheck-target-libcilkrts: installcheck-target-libcilkrts
+
+installcheck-target-libcilkrts: \
+    configure-target-libcilkrts 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing installcheck in $(TARGET_SUBDIR)/libcilkrts" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                  installcheck) \
+         || exit 1
+
+@endif target-libcilkrts
+
+.PHONY: maybe-mostlyclean-target-libcilkrts mostlyclean-target-libcilkrts
+maybe-mostlyclean-target-libcilkrts:
+@if target-libcilkrts
+maybe-mostlyclean-target-libcilkrts: mostlyclean-target-libcilkrts
+
+mostlyclean-target-libcilkrts: 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing mostlyclean in $(TARGET_SUBDIR)/libcilkrts" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                  mostlyclean) \
+         || exit 1
+
+@endif target-libcilkrts
+
+.PHONY: maybe-clean-target-libcilkrts clean-target-libcilkrts
+maybe-clean-target-libcilkrts:
+@if target-libcilkrts
+maybe-clean-target-libcilkrts: clean-target-libcilkrts
+
+clean-target-libcilkrts: 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing clean in $(TARGET_SUBDIR)/libcilkrts" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                  clean) \
+         || exit 1
+
+@endif target-libcilkrts
+
+.PHONY: maybe-distclean-target-libcilkrts distclean-target-libcilkrts
+maybe-distclean-target-libcilkrts:
+@if target-libcilkrts
+maybe-distclean-target-libcilkrts: distclean-target-libcilkrts
+
+distclean-target-libcilkrts: 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing distclean in $(TARGET_SUBDIR)/libcilkrts" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                  distclean) \
+         || exit 1
+
+@endif target-libcilkrts
+
+.PHONY: maybe-maintainer-clean-target-libcilkrts maintainer-clean-target-libcilkrts
+maybe-maintainer-clean-target-libcilkrts:
+@if target-libcilkrts
+maybe-maintainer-clean-target-libcilkrts: maintainer-clean-target-libcilkrts
+
+maintainer-clean-target-libcilkrts: 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libcilkrts/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing maintainer-clean in $(TARGET_SUBDIR)/libcilkrts" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libcilkrts && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                  maintainer-clean) \
+         || exit 1
+
+@endif target-libcilkrts
 
 
 
@@ -45901,6 +46890,7 @@ configure-stage3-target-libvtv: maybe-all-stage3-gcc
 configure-stage4-target-libvtv: maybe-all-stage4-gcc
 configure-stageprofile-target-libvtv: maybe-all-stageprofile-gcc
 configure-stagefeedback-target-libvtv: maybe-all-stagefeedback-gcc
+configure-target-libcilkrts: stage_last
 configure-target-libssp: stage_last
 configure-target-newlib: stage_last
 configure-stage1-target-libgcc: maybe-all-stage1-gcc
@@ -45955,6 +46945,7 @@ configure-target-boehm-gc: maybe-all-gcc
 configure-target-rda: maybe-all-gcc
 configure-target-libada: maybe-all-gcc
 configure-target-libgomp: maybe-all-gcc
+configure-target-libcilkrts: maybe-all-gcc
 configure-target-libitm: maybe-all-gcc
 configure-target-libatomic: maybe-all-gcc
 @endif gcc-no-bootstrap
@@ -46720,6 +47711,8 @@ configure-stage3-target-libvtv: maybe-all-stage3-target-libstdc++-v3
 configure-stage4-target-libvtv: maybe-all-stage4-target-libstdc++-v3
 configure-stageprofile-target-libvtv: maybe-all-stageprofile-target-libstdc++-v3
 configure-stagefeedback-target-libvtv: maybe-all-stagefeedback-target-libstdc++-v3
+configure-target-libcilkrts: maybe-all-target-libstdc++-v3
+configure-target-libcilkrts: maybe-all-gcc
 all-target-libstdc++-v3: maybe-configure-target-libgomp
 
 all-stage1-target-libstdc++-v3: maybe-configure-stage1-target-libgomp
@@ -46735,6 +47728,8 @@ install-target-libsanitizer: maybe-install-target-libstdc++-v3
 install-target-libsanitizer: maybe-install-target-libgcc
 install-target-libvtv: maybe-install-target-libstdc++-v3
 install-target-libvtv: maybe-install-target-libgcc
+install-target-libcilkrts: maybe-install-target-libstdc++-v3
+install-target-libcilkrts: maybe-install-target-libgcc
 install-target-libjava: maybe-install-target-libgcc
 install-target-libitm: maybe-install-target-libgcc
 install-target-libobjc: maybe-install-target-libgcc
@@ -46783,6 +47778,7 @@ configure-target-libstdc++-v3: maybe-all-target-libgcc
 configure-target-libsanitizer: maybe-all-target-libgcc
 configure-target-libvtv: maybe-all-target-libgcc
 configure-target-libssp: maybe-all-target-libgcc
+configure-target-libcilkrts: maybe-all-target-libgcc
 configure-target-newlib: maybe-all-target-libgcc
 configure-target-libbacktrace: maybe-all-target-libgcc
 configure-target-libquadmath: maybe-all-target-libgcc
@@ -46830,6 +47826,8 @@ configure-target-winsup: maybe-all-target-newlib maybe-all-target-libgloss
 
 
 configure-target-libffi: maybe-all-target-newlib maybe-all-target-libgloss
+configure-target-libcilkrts: maybe-all-target-newlib maybe-all-target-libgloss
+configure-target-libcilkrts: maybe-all-target-libstdc++-v3
 
 configure-target-libjava: maybe-all-target-newlib maybe-all-target-libgloss
 configure-target-libjava: maybe-all-target-libstdc++-v3
index 7bc49f74aef7932950df13485a9ffecf807b94a4..c95990a6f4ceb20b4f3c7488d5c2bf06294d923d 100755 (executable)
--- a/configure
+++ b/configure
@@ -2772,6 +2772,7 @@ target_libraries="target-libgcc \
                target-libgloss \
                target-newlib \
                target-libgomp \
+               target-libcilkrts \
                target-libatomic \
                target-libitm \
                target-libstdc++-v3 \
@@ -3164,6 +3165,25 @@ $as_echo "yes" >&6; }
     fi
 fi
 
+# Disable libcilkrts on unsupported systems.
+if test -d ${srcdir}/libcilkrts; then
+    if test x$enable_libcilkrts = x; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libcilkrts support" >&5
+$as_echo_n "checking for libcilkrts support... " >&6; }
+       if (srcdir=${srcdir}/libcilkrts; \
+               . ${srcdir}/configure.tgt; \
+               test -n "$UNSUPPORTED")
+       then
+           { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+           noconfigdirs="$noconfigdirs target-libcilkrts"
+       else
+           { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+       fi
+    fi
+fi
+
 # Disable libitm on unsupported systems.
 if test -d ${srcdir}/libitm; then
     if test x$enable_libitm = x; then
index 595b2b921546376efb0c9f1a9e4d42a420376168..140877ffedc3ff8c415bef2eadbaa03abf9e6ea2 100644 (file)
@@ -156,6 +156,7 @@ target_libraries="target-libgcc \
                target-libgloss \
                target-newlib \
                target-libgomp \
+               target-libcilkrts \
                target-libatomic \
                target-libitm \
                target-libstdc++-v3 \
@@ -506,6 +507,22 @@ if test -d ${srcdir}/libatomic; then
     fi
 fi
 
+# Disable libcilkrts on unsupported systems.
+if test -d ${srcdir}/libcilkrts; then
+    if test x$enable_libcilkrts = x; then
+       AC_MSG_CHECKING([for libcilkrts support])
+       if (srcdir=${srcdir}/libcilkrts; \
+               . ${srcdir}/configure.tgt; \
+               test -n "$UNSUPPORTED")
+       then
+           AC_MSG_RESULT([no])
+           noconfigdirs="$noconfigdirs target-libcilkrts"
+       else
+           AC_MSG_RESULT([yes])
+       fi
+    fi
+fi
+
 # Disable libitm on unsupported systems.
 if test -d ${srcdir}/libitm; then
     if test x$enable_libitm = x; then
diff --git a/libcilkrts/ChangeLog b/libcilkrts/ChangeLog
new file mode 100644 (file)
index 0000000..884e861
--- /dev/null
@@ -0,0 +1,105 @@
+2013-10-23  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       * libcilkrts/Makefile.am: New file.  Libcilkrts version 3902.
+       * libcilkrts/Makefile.in: Likewise
+       * libcilkrts/README: Likewise
+       * libcilkrts/aclocal.m4: Likewise
+       * libcilkrts/configure: Likewise
+       * libcilkrts/configure.ac: Likewise
+       * libcilkrts/include/cilk/cilk.h: Likewise
+       * libcilkrts/include/cilk/cilk_api.h: Likewise
+       * libcilkrts/include/cilk/cilk_api_linux.h: Likewise
+       * libcilkrts/include/cilk/cilk_stub.h: Likewise
+       * libcilkrts/include/cilk/cilk_undocumented.h: Likewise
+       * libcilkrts/include/cilk/common.h: Likewise
+       * libcilkrts/include/cilk/holder.h: Likewise
+       * libcilkrts/include/cilk/hyperobject_base.h: Likewise
+       * libcilkrts/include/cilk/metaprogramming.h: Likewise
+       * libcilkrts/include/cilk/reducer.h: Likewise
+       * libcilkrts/include/cilk/reducer_file.h: Likewise
+       * libcilkrts/include/cilk/reducer_list.h: Likewise
+       * libcilkrts/include/cilk/reducer_max.h: Likewise
+       * libcilkrts/include/cilk/reducer_min.h: Likewise
+       * libcilkrts/include/cilk/reducer_min_max.h: Likewise
+       * libcilkrts/include/cilk/reducer_opadd.h: Likewise
+       * libcilkrts/include/cilk/reducer_opand.h: Likewise
+       * libcilkrts/include/cilk/reducer_opmul.h: Likewise
+       * libcilkrts/include/cilk/reducer_opor.h: Likewise
+       * libcilkrts/include/cilk/reducer_opxor.h: Likewise
+       * libcilkrts/include/cilk/reducer_ostream.h: Likewise
+       * libcilkrts/include/cilk/reducer_string.h: Likewise
+       * libcilkrts/include/cilktools/cilkscreen.h: Likewise
+       * libcilkrts/include/cilktools/cilkview.h: Likewise
+       * libcilkrts/include/cilktools/fake_mutex.h: Likewise
+       * libcilkrts/include/cilktools/lock_guard.h: Likewise
+       * libcilkrts/include/internal/abi.h: Likewise
+       * libcilkrts/include/internal/cilk_fake.h: Likewise
+       * libcilkrts/include/internal/cilk_version.h: Likewise
+       * libcilkrts/include/internal/inspector-abi.h: Likewise
+       * libcilkrts/include/internal/metacall.h: Likewise
+       * libcilkrts/include/internal/rev.mk: Likewise
+       * libcilkrts/mk/cilk-version.mk: Likewise
+       * libcilkrts/mk/unix-common.mk: Likewise
+       * libcilkrts/runtime/acknowledgements.dox: Likewise
+       * libcilkrts/runtime/bug.cpp: Likewise
+       * libcilkrts/runtime/bug.h: Likewise
+       * libcilkrts/runtime/c_reducers.c: Likewise
+       * libcilkrts/runtime/cilk-abi-cilk-for.cpp: Likewise
+       * libcilkrts/runtime/cilk-abi-vla-internal.c: Likewise
+       * libcilkrts/runtime/cilk-abi-vla-internal.h: Likewise
+       * libcilkrts/runtime/cilk-abi-vla.c: Likewise
+       * libcilkrts/runtime/cilk-abi.c: Likewise
+       * libcilkrts/runtime/cilk-ittnotify.h: Likewise
+       * libcilkrts/runtime/cilk-tbb-interop.h: Likewise
+       * libcilkrts/runtime/cilk_api.c: Likewise
+       * libcilkrts/runtime/cilk_fiber-unix.cpp: Likewise
+       * libcilkrts/runtime/cilk_fiber-unix.h: Likewise
+       * libcilkrts/runtime/cilk_fiber.cpp: Likewise
+       * libcilkrts/runtime/cilk_fiber.h: Likewise
+       * libcilkrts/runtime/cilk_malloc.c: Likewise
+       * libcilkrts/runtime/cilk_malloc.h: Likewise
+       * libcilkrts/runtime/component.h: Likewise
+       * libcilkrts/runtime/doxygen-layout.xml: Likewise
+       * libcilkrts/runtime/doxygen.cfg: Likewise
+       * libcilkrts/runtime/except-gcc.cpp: Likewise
+       * libcilkrts/runtime/except-gcc.h: Likewise
+       * libcilkrts/runtime/except.h: Likewise
+       * libcilkrts/runtime/frame_malloc.c: Likewise
+       * libcilkrts/runtime/frame_malloc.h: Likewise
+       * libcilkrts/runtime/full_frame.c: Likewise
+       * libcilkrts/runtime/full_frame.h: Likewise
+       * libcilkrts/runtime/global_state.cpp: Likewise
+       * libcilkrts/runtime/global_state.h: Likewise
+       * libcilkrts/runtime/jmpbuf.c: Likewise
+       * libcilkrts/runtime/jmpbuf.h: Likewise
+       * libcilkrts/runtime/local_state.c: Likewise
+       * libcilkrts/runtime/local_state.h: Likewise
+       * libcilkrts/runtime/metacall_impl.c: Likewise
+       * libcilkrts/runtime/metacall_impl.h: Likewise
+       * libcilkrts/runtime/os-unix.c: Likewise
+       * libcilkrts/runtime/os.h: Likewise
+       * libcilkrts/runtime/os_mutex-unix.c: Likewise
+       * libcilkrts/runtime/os_mutex.h: Likewise
+       * libcilkrts/runtime/pedigrees.c: Likewise
+       * libcilkrts/runtime/pedigrees.h: Likewise
+       * libcilkrts/runtime/record-replay.cpp: Likewise
+       * libcilkrts/runtime/record-replay.h: Likewise
+       * libcilkrts/runtime/reducer_impl.cpp: Likewise
+       * libcilkrts/runtime/reducer_impl.h: Likewise
+       * libcilkrts/runtime/rts-common.h: Likewise
+       * libcilkrts/runtime/scheduler.c: Likewise
+       * libcilkrts/runtime/scheduler.h: Likewise
+       * libcilkrts/runtime/signal_node.c: Likewise
+       * libcilkrts/runtime/signal_node.h: Likewise
+       * libcilkrts/runtime/spin_mutex.c: Likewise
+       * libcilkrts/runtime/spin_mutex.h: Likewise
+       * libcilkrts/runtime/stacks.h: Likewise
+       * libcilkrts/runtime/stats.c: Likewise
+       * libcilkrts/runtime/stats.h: Likewise
+       * libcilkrts/runtime/symbol_test.c: Likewise
+       * libcilkrts/runtime/sysdep-unix.c: Likewise
+       * libcilkrts/runtime/sysdep.h: Likewise
+       * libcilkrts/runtime/unix_symbols.t: Likewise
+       * libcilkrts/runtime/worker_mutex.c: Likewise
+       * libcilkrts/runtime/worker_mutex.h: Likewise
+
diff --git a/libcilkrts/Makefile.am b/libcilkrts/Makefile.am
new file mode 100644 (file)
index 0000000..f332cfb
--- /dev/null
@@ -0,0 +1,173 @@
+#  @copyright
+#  Copyright (C) 2011, 2013, Intel Corporation
+#  All rights reserved.
+#  
+#  @copyright
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions
+#  are met:
+#  
+#    * Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#    * Neither the name of Intel Corporation nor the names of its
+#      contributors may be used to endorse or promote products derived
+#      from this software without specific prior written permission.
+#  
+#  @copyright
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+#  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+#  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+#  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+#  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+
+AUTOMAKE_OPTIONS = foreign
+
+# Use when building GCC
+ACLOCAL_AMFLAGS = -I .. -I ../config
+
+# Compiler and linker flags.
+GENERAL_FLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/runtime -I$(top_srcdir)/runtime/config/$(config_dir) -DIN_CILK_RUNTIME=1
+GENERAL_FLAGS += -D_Cilk_spawn="" -D_Cilk_sync="" -D_Cilk_for=for
+
+# Enable Intel Cilk Plus extension
+GENERAL_FLAGS += -fcilkplus
+
+AM_CFLAGS = $(GENERAL_FLAGS) -std=c99
+AM_CPPFLAGS = $(GENERAL_FLAGS)
+AM_LDFLAGS = -lpthread -ldl
+
+# Target list.
+toolexeclib_LTLIBRARIES = libcilkrts.la
+
+libcilkrts_la_SOURCES =            \
+  runtime/config/$(config_dir)/cilk-abi-vla.c           \
+  runtime/config/$(config_dir)/os-unix-sysdep.c \
+  runtime/bug.cpp                  \
+  runtime/cilk-abi.c               \
+  runtime/cilk-abi-cilk-for.cpp    \
+  runtime/cilk-abi-vla-internal.c  \
+  runtime/cilk_api.c               \
+  runtime/cilk_fiber.cpp           \
+  runtime/cilk_fiber-unix.cpp      \
+  runtime/cilk_malloc.c            \
+  runtime/c_reducers.c             \
+  runtime/except-gcc.cpp           \
+  runtime/frame_malloc.c           \
+  runtime/full_frame.c             \
+  runtime/global_state.cpp         \
+  runtime/jmpbuf.c                 \
+  runtime/local_state.c            \
+  runtime/metacall_impl.c          \
+  runtime/os_mutex-unix.c          \
+  runtime/os-unix.c                \
+  runtime/pedigrees.c              \
+  runtime/record-replay.cpp        \
+  runtime/reducer_impl.cpp         \
+  runtime/scheduler.c              \
+  runtime/signal_node.c            \
+  runtime/spin_mutex.c             \
+  runtime/stats.c                  \
+  runtime/symbol_test.c            \
+  runtime/sysdep-unix.c            \
+  runtime/worker_mutex.c
+
+
+# Load the $(REVISION) value.
+include include/internal/rev.mk
+
+#libcilkrts_la_LDFLAGS  = -rpath '$(libdir)'
+libcilkrts_la_LDFLAGS = -version-info 5:0:0
+libcilkrts_la_LDFLAGS += -lpthread -ldl
+
+# If we're building on Linux, use the Linux version script
+if LINUX_LINKER_SCRIPT
+    libcilkrts_la_LDFLAGS += -Wl,--version-script,$(srcdir)/runtime/linux-symbols.ver
+endif
+
+# If we're building on MacOS, use the Mac versioning
+if MAC_LINKER_SCRIPT
+  libcilkrts_la_LDFLAGS += -Wl,-exported_symbols_list,$(srcdir)/runtime/mac-symbols.txt
+endif
+
+
+# Hack for Cygwin
+libcilkrts_la_LDFLAGS += -no-undefined
+
+# C/C++ header files for Cilk.
+cilkincludedir = $(includedir)/cilk
+cilkinclude_HEADERS =              \
+  include/cilk/cilk_api.h          \
+  include/cilk/cilk_api_linux.h    \
+  include/cilk/cilk.h              \
+  include/cilk/cilk_stub.h         \
+  include/cilk/cilk_undocumented.h \
+  include/cilk/common.h            \
+  include/cilk/holder.h            \
+  include/cilk/hyperobject_base.h  \
+  include/cilk/metaprogramming.h   \
+  include/cilk/reducer_file.h      \
+  include/cilk/reducer.h           \
+  include/cilk/reducer_list.h      \
+  include/cilk/reducer_max.h       \
+  include/cilk/reducer_min.h       \
+  include/cilk/reducer_min_max.h   \
+  include/cilk/reducer_opadd.h     \
+  include/cilk/reducer_opand.h     \
+  include/cilk/reducer_opmul.h     \
+  include/cilk/reducer_opor.h      \
+  include/cilk/reducer_opxor.h     \
+  include/cilk/reducer_ostream.h   \
+  include/cilk/reducer_string.h
+
+
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+       "AR_FLAGS=$(AR_FLAGS)" \
+       "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+       "CFLAGS=$(CFLAGS)" \
+       "CXXFLAGS=$(CXXFLAGS)" \
+       "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+       "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+       "INSTALL=$(INSTALL)" \
+       "INSTALL_DATA=$(INSTALL_DATA)" \
+       "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+       "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+       "JC1FLAGS=$(JC1FLAGS)" \
+       "LDFLAGS=$(LDFLAGS)" \
+       "LIBCFLAGS=$(LIBCFLAGS)" \
+       "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+       "MAKE=$(MAKE)" \
+       "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+       "PICFLAG=$(PICFLAG)" \
+       "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+       "SHELL=$(SHELL)" \
+       "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+       "exec_prefix=$(exec_prefix)" \
+       "infodir=$(infodir)" \
+       "libdir=$(libdir)" \
+       "prefix=$(prefix)" \
+       "includedir=$(includedir)" \
+       "AR=$(AR)" \
+       "AS=$(AS)" \
+       "LD=$(LD)" \
+       "LIBCFLAGS=$(LIBCFLAGS)" \
+       "NM=$(NM)" \
+       "PICFLAG=$(PICFLAG)" \
+       "RANLIB=$(RANLIB)" \
+       "DESTDIR=$(DESTDIR)"
+
+MAKEOVERRIDES=
+
diff --git a/libcilkrts/Makefile.in b/libcilkrts/Makefile.in
new file mode 100644 (file)
index 0000000..ecf8080
--- /dev/null
@@ -0,0 +1,1045 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  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@
+
+#  @copyright
+#  Copyright (C) 2011, 2013, Intel Corporation
+#  All rights reserved.
+#  
+#  @copyright
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions
+#  are met:
+#  
+#    * Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#    * Neither the name of Intel Corporation nor the names of its
+#      contributors may be used to endorse or promote products derived
+#      from this software without specific prior written permission.
+#  
+#  @copyright
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+#  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+#  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+#  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+#  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+
+#########################################################################
+#
+#  @copyright
+#  Copyright (C) 2011-2013, Intel Corporation
+#  All rights reserved.
+#  
+#  @copyright
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions
+#  are met:
+#  
+#    * Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#    * Neither the name of Intel Corporation nor the names of its
+#      contributors may be used to endorse or promote products derived
+#      from this software without specific prior written permission.
+#  
+#  @copyright
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+#  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+#  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+#  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+#  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+###########################################################################
+
+# DO NOT EDIT THIS FILE!
+#
+# It was automatically generated by cilkrts/include/internal/Makefile
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@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@
+DIST_COMMON = $(srcdir)/include/internal/rev.mk README ChangeLog \
+       $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+       $(top_srcdir)/configure $(am__configure_deps) \
+       $(srcdir)/../mkinstalldirs $(srcdir)/../depcomp \
+       $(cilkinclude_HEADERS)
+
+# If we're building on Linux, use the Linux version script
+@LINUX_LINKER_SCRIPT_TRUE@am__append_1 = -Wl,--version-script,$(srcdir)/runtime/linux-symbols.ver
+
+# If we're building on MacOS, use the Mac versioning
+@MAC_LINKER_SCRIPT_TRUE@am__append_2 = -Wl,-exported_symbols_list,$(srcdir)/runtime/mac-symbols.txt
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
+       $(top_srcdir)/../config/lead-dot.m4 \
+       $(top_srcdir)/../config/multi.m4 \
+       $(top_srcdir)/../config/override.m4 \
+       $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
+       $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
+       $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+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 = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(toolexeclibdir)" \
+       "$(DESTDIR)$(cilkincludedir)"
+LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
+libcilkrts_la_LIBADD =
+am_libcilkrts_la_OBJECTS = cilk-abi-vla.lo os-unix-sysdep.lo bug.lo \
+       cilk-abi.lo cilk-abi-cilk-for.lo cilk-abi-vla-internal.lo \
+       cilk_api.lo cilk_fiber.lo cilk_fiber-unix.lo cilk_malloc.lo \
+       c_reducers.lo except-gcc.lo frame_malloc.lo full_frame.lo \
+       global_state.lo jmpbuf.lo local_state.lo metacall_impl.lo \
+       os_mutex-unix.lo os-unix.lo pedigrees.lo record-replay.lo \
+       reducer_impl.lo scheduler.lo signal_node.lo spin_mutex.lo \
+       stats.lo symbol_test.lo sysdep-unix.lo worker_mutex.lo
+libcilkrts_la_OBJECTS = $(am_libcilkrts_la_OBJECTS)
+libcilkrts_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+       $(CXXFLAGS) $(libcilkrts_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/../depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+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 $@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+       --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+       --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+       $(LDFLAGS) -o $@
+SOURCES = $(libcilkrts_la_SOURCES)
+MULTISRCTOP = 
+MULTIBUILDTOP = 
+MULTIDIRS = 
+MULTISUBDIR = 
+MULTIDO = true
+MULTICLEAN = true
+HEADERS = $(cilkinclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+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_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+config_dir = @config_dir@
+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@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+multi_basedir = @multi_basedir@
+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@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign
+
+# Use when building GCC
+ACLOCAL_AMFLAGS = -I .. -I ../config
+
+# Compiler and linker flags.
+
+# Enable Intel Cilk Plus extension
+GENERAL_FLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/runtime \
+       -I$(top_srcdir)/runtime/config/$(config_dir) \
+       -DIN_CILK_RUNTIME=1 -D_Cilk_spawn="" -D_Cilk_sync="" \
+       -D_Cilk_for=for -fcilkplus
+AM_CFLAGS = $(GENERAL_FLAGS) -std=c99
+AM_CPPFLAGS = $(GENERAL_FLAGS)
+AM_LDFLAGS = -lpthread -ldl
+
+# Target list.
+toolexeclib_LTLIBRARIES = libcilkrts.la
+libcilkrts_la_SOURCES = \
+  runtime/config/$(config_dir)/cilk-abi-vla.c           \
+  runtime/config/$(config_dir)/os-unix-sysdep.c \
+  runtime/bug.cpp                  \
+  runtime/cilk-abi.c               \
+  runtime/cilk-abi-cilk-for.cpp    \
+  runtime/cilk-abi-vla-internal.c  \
+  runtime/cilk_api.c               \
+  runtime/cilk_fiber.cpp           \
+  runtime/cilk_fiber-unix.cpp      \
+  runtime/cilk_malloc.c            \
+  runtime/c_reducers.c             \
+  runtime/except-gcc.cpp           \
+  runtime/frame_malloc.c           \
+  runtime/full_frame.c             \
+  runtime/global_state.cpp         \
+  runtime/jmpbuf.c                 \
+  runtime/local_state.c            \
+  runtime/metacall_impl.c          \
+  runtime/os_mutex-unix.c          \
+  runtime/os-unix.c                \
+  runtime/pedigrees.c              \
+  runtime/record-replay.cpp        \
+  runtime/reducer_impl.cpp         \
+  runtime/scheduler.c              \
+  runtime/signal_node.c            \
+  runtime/spin_mutex.c             \
+  runtime/stats.c                  \
+  runtime/symbol_test.c            \
+  runtime/sysdep-unix.c            \
+  runtime/worker_mutex.c
+
+CILK_REVISION = 3902
+
+# Load the $(REVISION) value.
+
+#libcilkrts_la_LDFLAGS  = -rpath '$(libdir)'
+
+# Hack for Cygwin
+libcilkrts_la_LDFLAGS = -version-info 5:0:0 -lpthread -ldl \
+       $(am__append_1) $(am__append_2) -no-undefined
+
+# C/C++ header files for Cilk.
+cilkincludedir = $(includedir)/cilk
+cilkinclude_HEADERS = \
+  include/cilk/cilk_api.h          \
+  include/cilk/cilk_api_linux.h    \
+  include/cilk/cilk.h              \
+  include/cilk/cilk_stub.h         \
+  include/cilk/cilk_undocumented.h \
+  include/cilk/common.h            \
+  include/cilk/holder.h            \
+  include/cilk/hyperobject_base.h  \
+  include/cilk/metaprogramming.h   \
+  include/cilk/reducer_file.h      \
+  include/cilk/reducer.h           \
+  include/cilk/reducer_list.h      \
+  include/cilk/reducer_max.h       \
+  include/cilk/reducer_min.h       \
+  include/cilk/reducer_min_max.h   \
+  include/cilk/reducer_opadd.h     \
+  include/cilk/reducer_opand.h     \
+  include/cilk/reducer_opmul.h     \
+  include/cilk/reducer_opor.h      \
+  include/cilk/reducer_opxor.h     \
+  include/cilk/reducer_ostream.h   \
+  include/cilk/reducer_string.h
+
+
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+       "AR_FLAGS=$(AR_FLAGS)" \
+       "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+       "CFLAGS=$(CFLAGS)" \
+       "CXXFLAGS=$(CXXFLAGS)" \
+       "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+       "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+       "INSTALL=$(INSTALL)" \
+       "INSTALL_DATA=$(INSTALL_DATA)" \
+       "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+       "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+       "JC1FLAGS=$(JC1FLAGS)" \
+       "LDFLAGS=$(LDFLAGS)" \
+       "LIBCFLAGS=$(LIBCFLAGS)" \
+       "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+       "MAKE=$(MAKE)" \
+       "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+       "PICFLAG=$(PICFLAG)" \
+       "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+       "SHELL=$(SHELL)" \
+       "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+       "exec_prefix=$(exec_prefix)" \
+       "infodir=$(infodir)" \
+       "libdir=$(libdir)" \
+       "prefix=$(prefix)" \
+       "includedir=$(includedir)" \
+       "AR=$(AR)" \
+       "AS=$(AS)" \
+       "LD=$(LD)" \
+       "LIBCFLAGS=$(LIBCFLAGS)" \
+       "NM=$(NM)" \
+       "PICFLAG=$(PICFLAG)" \
+       "RANLIB=$(RANLIB)" \
+       "DESTDIR=$(DESTDIR)"
+
+MAKEOVERRIDES = 
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cpp .lo .o .obj
+am--refresh:
+       @:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(srcdir)/include/internal/rev.mk $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+             echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+             $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+               && exit 0; \
+             exit 1;; \
+         esac; \
+       done; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+       $(am__cd) $(top_srcdir) && \
+         $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       @case '$?' in \
+         *config.status*) \
+           echo ' $(SHELL) ./config.status'; \
+           $(SHELL) ./config.status;; \
+         *) \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+       esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+       $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+       $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)"
+       @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
+       list2=; for p in $$list; do \
+         if test -f $$p; then \
+           list2="$$list2 $$p"; \
+         else :; fi; \
+       done; \
+       test -z "$$list2" || { \
+         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(toolexeclibdir)'"; \
+         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(toolexeclibdir)"; \
+       }
+
+uninstall-toolexeclibLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
+       for p in $$list; do \
+         $(am__strip_dir) \
+         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(toolexeclibdir)/$$f'"; \
+         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(toolexeclibdir)/$$f"; \
+       done
+
+clean-toolexeclibLTLIBRARIES:
+       -test -z "$(toolexeclib_LTLIBRARIES)" || rm -f $(toolexeclib_LTLIBRARIES)
+       @list='$(toolexeclib_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
+libcilkrts.la: $(libcilkrts_la_OBJECTS) $(libcilkrts_la_DEPENDENCIES) 
+       $(libcilkrts_la_LINK) -rpath $(toolexeclibdir) $(libcilkrts_la_OBJECTS) $(libcilkrts_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bug.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_reducers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cilk-abi-cilk-for.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cilk-abi-vla-internal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cilk-abi-vla.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cilk-abi.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cilk_api.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cilk_fiber-unix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cilk_fiber.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cilk_malloc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/except-gcc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame_malloc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/full_frame.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/global_state.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jmpbuf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/local_state.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metacall_impl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os-unix-sysdep.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os-unix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os_mutex-unix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pedigrees.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/record-replay.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reducer_impl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scheduler.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal_node.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spin_mutex.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stats.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol_test.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sysdep-unix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/worker_mutex.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@   $(am__mv) $(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@   $(am__mv) $(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@   $(am__mv) $(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 $@ $<
+
+cilk-abi-vla.lo: runtime/config/$(config_dir)/cilk-abi-vla.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cilk-abi-vla.lo -MD -MP -MF $(DEPDIR)/cilk-abi-vla.Tpo -c -o cilk-abi-vla.lo `test -f 'runtime/config/$(config_dir)/cilk-abi-vla.c' || echo '$(srcdir)/'`runtime/config/$(config_dir)/cilk-abi-vla.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/cilk-abi-vla.Tpo $(DEPDIR)/cilk-abi-vla.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/config/$(config_dir)/cilk-abi-vla.c' object='cilk-abi-vla.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cilk-abi-vla.lo `test -f 'runtime/config/$(config_dir)/cilk-abi-vla.c' || echo '$(srcdir)/'`runtime/config/$(config_dir)/cilk-abi-vla.c
+
+os-unix-sysdep.lo: runtime/config/$(config_dir)/os-unix-sysdep.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT os-unix-sysdep.lo -MD -MP -MF $(DEPDIR)/os-unix-sysdep.Tpo -c -o os-unix-sysdep.lo `test -f 'runtime/config/$(config_dir)/os-unix-sysdep.c' || echo '$(srcdir)/'`runtime/config/$(config_dir)/os-unix-sysdep.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/os-unix-sysdep.Tpo $(DEPDIR)/os-unix-sysdep.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/config/$(config_dir)/os-unix-sysdep.c' object='os-unix-sysdep.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o os-unix-sysdep.lo `test -f 'runtime/config/$(config_dir)/os-unix-sysdep.c' || echo '$(srcdir)/'`runtime/config/$(config_dir)/os-unix-sysdep.c
+
+cilk-abi.lo: runtime/cilk-abi.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cilk-abi.lo -MD -MP -MF $(DEPDIR)/cilk-abi.Tpo -c -o cilk-abi.lo `test -f 'runtime/cilk-abi.c' || echo '$(srcdir)/'`runtime/cilk-abi.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/cilk-abi.Tpo $(DEPDIR)/cilk-abi.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/cilk-abi.c' object='cilk-abi.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cilk-abi.lo `test -f 'runtime/cilk-abi.c' || echo '$(srcdir)/'`runtime/cilk-abi.c
+
+cilk-abi-vla-internal.lo: runtime/cilk-abi-vla-internal.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cilk-abi-vla-internal.lo -MD -MP -MF $(DEPDIR)/cilk-abi-vla-internal.Tpo -c -o cilk-abi-vla-internal.lo `test -f 'runtime/cilk-abi-vla-internal.c' || echo '$(srcdir)/'`runtime/cilk-abi-vla-internal.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/cilk-abi-vla-internal.Tpo $(DEPDIR)/cilk-abi-vla-internal.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/cilk-abi-vla-internal.c' object='cilk-abi-vla-internal.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cilk-abi-vla-internal.lo `test -f 'runtime/cilk-abi-vla-internal.c' || echo '$(srcdir)/'`runtime/cilk-abi-vla-internal.c
+
+cilk_api.lo: runtime/cilk_api.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cilk_api.lo -MD -MP -MF $(DEPDIR)/cilk_api.Tpo -c -o cilk_api.lo `test -f 'runtime/cilk_api.c' || echo '$(srcdir)/'`runtime/cilk_api.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/cilk_api.Tpo $(DEPDIR)/cilk_api.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/cilk_api.c' object='cilk_api.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cilk_api.lo `test -f 'runtime/cilk_api.c' || echo '$(srcdir)/'`runtime/cilk_api.c
+
+cilk_malloc.lo: runtime/cilk_malloc.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cilk_malloc.lo -MD -MP -MF $(DEPDIR)/cilk_malloc.Tpo -c -o cilk_malloc.lo `test -f 'runtime/cilk_malloc.c' || echo '$(srcdir)/'`runtime/cilk_malloc.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/cilk_malloc.Tpo $(DEPDIR)/cilk_malloc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/cilk_malloc.c' object='cilk_malloc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cilk_malloc.lo `test -f 'runtime/cilk_malloc.c' || echo '$(srcdir)/'`runtime/cilk_malloc.c
+
+c_reducers.lo: runtime/c_reducers.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT c_reducers.lo -MD -MP -MF $(DEPDIR)/c_reducers.Tpo -c -o c_reducers.lo `test -f 'runtime/c_reducers.c' || echo '$(srcdir)/'`runtime/c_reducers.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/c_reducers.Tpo $(DEPDIR)/c_reducers.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/c_reducers.c' object='c_reducers.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o c_reducers.lo `test -f 'runtime/c_reducers.c' || echo '$(srcdir)/'`runtime/c_reducers.c
+
+frame_malloc.lo: runtime/frame_malloc.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT frame_malloc.lo -MD -MP -MF $(DEPDIR)/frame_malloc.Tpo -c -o frame_malloc.lo `test -f 'runtime/frame_malloc.c' || echo '$(srcdir)/'`runtime/frame_malloc.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/frame_malloc.Tpo $(DEPDIR)/frame_malloc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/frame_malloc.c' object='frame_malloc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o frame_malloc.lo `test -f 'runtime/frame_malloc.c' || echo '$(srcdir)/'`runtime/frame_malloc.c
+
+full_frame.lo: runtime/full_frame.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT full_frame.lo -MD -MP -MF $(DEPDIR)/full_frame.Tpo -c -o full_frame.lo `test -f 'runtime/full_frame.c' || echo '$(srcdir)/'`runtime/full_frame.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/full_frame.Tpo $(DEPDIR)/full_frame.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/full_frame.c' object='full_frame.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o full_frame.lo `test -f 'runtime/full_frame.c' || echo '$(srcdir)/'`runtime/full_frame.c
+
+jmpbuf.lo: runtime/jmpbuf.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT jmpbuf.lo -MD -MP -MF $(DEPDIR)/jmpbuf.Tpo -c -o jmpbuf.lo `test -f 'runtime/jmpbuf.c' || echo '$(srcdir)/'`runtime/jmpbuf.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/jmpbuf.Tpo $(DEPDIR)/jmpbuf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/jmpbuf.c' object='jmpbuf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o jmpbuf.lo `test -f 'runtime/jmpbuf.c' || echo '$(srcdir)/'`runtime/jmpbuf.c
+
+local_state.lo: runtime/local_state.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT local_state.lo -MD -MP -MF $(DEPDIR)/local_state.Tpo -c -o local_state.lo `test -f 'runtime/local_state.c' || echo '$(srcdir)/'`runtime/local_state.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/local_state.Tpo $(DEPDIR)/local_state.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/local_state.c' object='local_state.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o local_state.lo `test -f 'runtime/local_state.c' || echo '$(srcdir)/'`runtime/local_state.c
+
+metacall_impl.lo: runtime/metacall_impl.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT metacall_impl.lo -MD -MP -MF $(DEPDIR)/metacall_impl.Tpo -c -o metacall_impl.lo `test -f 'runtime/metacall_impl.c' || echo '$(srcdir)/'`runtime/metacall_impl.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/metacall_impl.Tpo $(DEPDIR)/metacall_impl.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/metacall_impl.c' object='metacall_impl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o metacall_impl.lo `test -f 'runtime/metacall_impl.c' || echo '$(srcdir)/'`runtime/metacall_impl.c
+
+os_mutex-unix.lo: runtime/os_mutex-unix.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT os_mutex-unix.lo -MD -MP -MF $(DEPDIR)/os_mutex-unix.Tpo -c -o os_mutex-unix.lo `test -f 'runtime/os_mutex-unix.c' || echo '$(srcdir)/'`runtime/os_mutex-unix.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/os_mutex-unix.Tpo $(DEPDIR)/os_mutex-unix.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/os_mutex-unix.c' object='os_mutex-unix.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o os_mutex-unix.lo `test -f 'runtime/os_mutex-unix.c' || echo '$(srcdir)/'`runtime/os_mutex-unix.c
+
+os-unix.lo: runtime/os-unix.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT os-unix.lo -MD -MP -MF $(DEPDIR)/os-unix.Tpo -c -o os-unix.lo `test -f 'runtime/os-unix.c' || echo '$(srcdir)/'`runtime/os-unix.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/os-unix.Tpo $(DEPDIR)/os-unix.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/os-unix.c' object='os-unix.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o os-unix.lo `test -f 'runtime/os-unix.c' || echo '$(srcdir)/'`runtime/os-unix.c
+
+pedigrees.lo: runtime/pedigrees.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pedigrees.lo -MD -MP -MF $(DEPDIR)/pedigrees.Tpo -c -o pedigrees.lo `test -f 'runtime/pedigrees.c' || echo '$(srcdir)/'`runtime/pedigrees.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/pedigrees.Tpo $(DEPDIR)/pedigrees.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/pedigrees.c' object='pedigrees.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pedigrees.lo `test -f 'runtime/pedigrees.c' || echo '$(srcdir)/'`runtime/pedigrees.c
+
+scheduler.lo: runtime/scheduler.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT scheduler.lo -MD -MP -MF $(DEPDIR)/scheduler.Tpo -c -o scheduler.lo `test -f 'runtime/scheduler.c' || echo '$(srcdir)/'`runtime/scheduler.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/scheduler.Tpo $(DEPDIR)/scheduler.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/scheduler.c' object='scheduler.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o scheduler.lo `test -f 'runtime/scheduler.c' || echo '$(srcdir)/'`runtime/scheduler.c
+
+signal_node.lo: runtime/signal_node.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT signal_node.lo -MD -MP -MF $(DEPDIR)/signal_node.Tpo -c -o signal_node.lo `test -f 'runtime/signal_node.c' || echo '$(srcdir)/'`runtime/signal_node.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/signal_node.Tpo $(DEPDIR)/signal_node.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/signal_node.c' object='signal_node.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o signal_node.lo `test -f 'runtime/signal_node.c' || echo '$(srcdir)/'`runtime/signal_node.c
+
+spin_mutex.lo: runtime/spin_mutex.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spin_mutex.lo -MD -MP -MF $(DEPDIR)/spin_mutex.Tpo -c -o spin_mutex.lo `test -f 'runtime/spin_mutex.c' || echo '$(srcdir)/'`runtime/spin_mutex.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/spin_mutex.Tpo $(DEPDIR)/spin_mutex.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/spin_mutex.c' object='spin_mutex.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spin_mutex.lo `test -f 'runtime/spin_mutex.c' || echo '$(srcdir)/'`runtime/spin_mutex.c
+
+stats.lo: runtime/stats.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stats.lo -MD -MP -MF $(DEPDIR)/stats.Tpo -c -o stats.lo `test -f 'runtime/stats.c' || echo '$(srcdir)/'`runtime/stats.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/stats.Tpo $(DEPDIR)/stats.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/stats.c' object='stats.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stats.lo `test -f 'runtime/stats.c' || echo '$(srcdir)/'`runtime/stats.c
+
+symbol_test.lo: runtime/symbol_test.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT symbol_test.lo -MD -MP -MF $(DEPDIR)/symbol_test.Tpo -c -o symbol_test.lo `test -f 'runtime/symbol_test.c' || echo '$(srcdir)/'`runtime/symbol_test.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/symbol_test.Tpo $(DEPDIR)/symbol_test.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/symbol_test.c' object='symbol_test.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o symbol_test.lo `test -f 'runtime/symbol_test.c' || echo '$(srcdir)/'`runtime/symbol_test.c
+
+sysdep-unix.lo: runtime/sysdep-unix.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sysdep-unix.lo -MD -MP -MF $(DEPDIR)/sysdep-unix.Tpo -c -o sysdep-unix.lo `test -f 'runtime/sysdep-unix.c' || echo '$(srcdir)/'`runtime/sysdep-unix.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/sysdep-unix.Tpo $(DEPDIR)/sysdep-unix.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/sysdep-unix.c' object='sysdep-unix.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sysdep-unix.lo `test -f 'runtime/sysdep-unix.c' || echo '$(srcdir)/'`runtime/sysdep-unix.c
+
+worker_mutex.lo: runtime/worker_mutex.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT worker_mutex.lo -MD -MP -MF $(DEPDIR)/worker_mutex.Tpo -c -o worker_mutex.lo `test -f 'runtime/worker_mutex.c' || echo '$(srcdir)/'`runtime/worker_mutex.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/worker_mutex.Tpo $(DEPDIR)/worker_mutex.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/worker_mutex.c' object='worker_mutex.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o worker_mutex.lo `test -f 'runtime/worker_mutex.c' || echo '$(srcdir)/'`runtime/worker_mutex.c
+
+.cpp.o:
+@am__fastdepCXX_TRUE@  $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@  $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@  $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@  $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@  $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@  $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+bug.lo: runtime/bug.cpp
+@am__fastdepCXX_TRUE@  $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT bug.lo -MD -MP -MF $(DEPDIR)/bug.Tpo -c -o bug.lo `test -f 'runtime/bug.cpp' || echo '$(srcdir)/'`runtime/bug.cpp
+@am__fastdepCXX_TRUE@  $(am__mv) $(DEPDIR)/bug.Tpo $(DEPDIR)/bug.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='runtime/bug.cpp' object='bug.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bug.lo `test -f 'runtime/bug.cpp' || echo '$(srcdir)/'`runtime/bug.cpp
+
+cilk-abi-cilk-for.lo: runtime/cilk-abi-cilk-for.cpp
+@am__fastdepCXX_TRUE@  $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cilk-abi-cilk-for.lo -MD -MP -MF $(DEPDIR)/cilk-abi-cilk-for.Tpo -c -o cilk-abi-cilk-for.lo `test -f 'runtime/cilk-abi-cilk-for.cpp' || echo '$(srcdir)/'`runtime/cilk-abi-cilk-for.cpp
+@am__fastdepCXX_TRUE@  $(am__mv) $(DEPDIR)/cilk-abi-cilk-for.Tpo $(DEPDIR)/cilk-abi-cilk-for.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='runtime/cilk-abi-cilk-for.cpp' object='cilk-abi-cilk-for.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cilk-abi-cilk-for.lo `test -f 'runtime/cilk-abi-cilk-for.cpp' || echo '$(srcdir)/'`runtime/cilk-abi-cilk-for.cpp
+
+cilk_fiber.lo: runtime/cilk_fiber.cpp
+@am__fastdepCXX_TRUE@  $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cilk_fiber.lo -MD -MP -MF $(DEPDIR)/cilk_fiber.Tpo -c -o cilk_fiber.lo `test -f 'runtime/cilk_fiber.cpp' || echo '$(srcdir)/'`runtime/cilk_fiber.cpp
+@am__fastdepCXX_TRUE@  $(am__mv) $(DEPDIR)/cilk_fiber.Tpo $(DEPDIR)/cilk_fiber.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='runtime/cilk_fiber.cpp' object='cilk_fiber.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cilk_fiber.lo `test -f 'runtime/cilk_fiber.cpp' || echo '$(srcdir)/'`runtime/cilk_fiber.cpp
+
+cilk_fiber-unix.lo: runtime/cilk_fiber-unix.cpp
+@am__fastdepCXX_TRUE@  $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cilk_fiber-unix.lo -MD -MP -MF $(DEPDIR)/cilk_fiber-unix.Tpo -c -o cilk_fiber-unix.lo `test -f 'runtime/cilk_fiber-unix.cpp' || echo '$(srcdir)/'`runtime/cilk_fiber-unix.cpp
+@am__fastdepCXX_TRUE@  $(am__mv) $(DEPDIR)/cilk_fiber-unix.Tpo $(DEPDIR)/cilk_fiber-unix.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='runtime/cilk_fiber-unix.cpp' object='cilk_fiber-unix.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cilk_fiber-unix.lo `test -f 'runtime/cilk_fiber-unix.cpp' || echo '$(srcdir)/'`runtime/cilk_fiber-unix.cpp
+
+except-gcc.lo: runtime/except-gcc.cpp
+@am__fastdepCXX_TRUE@  $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT except-gcc.lo -MD -MP -MF $(DEPDIR)/except-gcc.Tpo -c -o except-gcc.lo `test -f 'runtime/except-gcc.cpp' || echo '$(srcdir)/'`runtime/except-gcc.cpp
+@am__fastdepCXX_TRUE@  $(am__mv) $(DEPDIR)/except-gcc.Tpo $(DEPDIR)/except-gcc.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='runtime/except-gcc.cpp' object='except-gcc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o except-gcc.lo `test -f 'runtime/except-gcc.cpp' || echo '$(srcdir)/'`runtime/except-gcc.cpp
+
+global_state.lo: runtime/global_state.cpp
+@am__fastdepCXX_TRUE@  $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT global_state.lo -MD -MP -MF $(DEPDIR)/global_state.Tpo -c -o global_state.lo `test -f 'runtime/global_state.cpp' || echo '$(srcdir)/'`runtime/global_state.cpp
+@am__fastdepCXX_TRUE@  $(am__mv) $(DEPDIR)/global_state.Tpo $(DEPDIR)/global_state.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='runtime/global_state.cpp' object='global_state.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o global_state.lo `test -f 'runtime/global_state.cpp' || echo '$(srcdir)/'`runtime/global_state.cpp
+
+record-replay.lo: runtime/record-replay.cpp
+@am__fastdepCXX_TRUE@  $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT record-replay.lo -MD -MP -MF $(DEPDIR)/record-replay.Tpo -c -o record-replay.lo `test -f 'runtime/record-replay.cpp' || echo '$(srcdir)/'`runtime/record-replay.cpp
+@am__fastdepCXX_TRUE@  $(am__mv) $(DEPDIR)/record-replay.Tpo $(DEPDIR)/record-replay.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='runtime/record-replay.cpp' object='record-replay.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o record-replay.lo `test -f 'runtime/record-replay.cpp' || echo '$(srcdir)/'`runtime/record-replay.cpp
+
+reducer_impl.lo: runtime/reducer_impl.cpp
+@am__fastdepCXX_TRUE@  $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT reducer_impl.lo -MD -MP -MF $(DEPDIR)/reducer_impl.Tpo -c -o reducer_impl.lo `test -f 'runtime/reducer_impl.cpp' || echo '$(srcdir)/'`runtime/reducer_impl.cpp
+@am__fastdepCXX_TRUE@  $(am__mv) $(DEPDIR)/reducer_impl.Tpo $(DEPDIR)/reducer_impl.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='runtime/reducer_impl.cpp' object='reducer_impl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o reducer_impl.lo `test -f 'runtime/reducer_impl.cpp' || echo '$(srcdir)/'`runtime/reducer_impl.cpp
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool config.lt
+
+# GNU Make needs to see an explicit $(MAKE) variable in the command it
+# runs to enable its job server during parallel builds.  Hence the
+# comments below.
+all-multi:
+       $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE)
+install-multi:
+       $(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do # $(MAKE)
+
+mostlyclean-multi:
+       $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean # $(MAKE)
+clean-multi:
+       $(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean # $(MAKE)
+distclean-multi:
+       $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE)
+maintainer-clean-multi:
+       $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE)
+install-cilkincludeHEADERS: $(cilkinclude_HEADERS)
+       @$(NORMAL_INSTALL)
+       test -z "$(cilkincludedir)" || $(MKDIR_P) "$(DESTDIR)$(cilkincludedir)"
+       @list='$(cilkinclude_HEADERS)'; test -n "$(cilkincludedir)" || list=; \
+       for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         echo "$$d$$p"; \
+       done | $(am__base_list) | \
+       while read files; do \
+         echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(cilkincludedir)'"; \
+         $(INSTALL_HEADER) $$files "$(DESTDIR)$(cilkincludedir)" || exit $$?; \
+       done
+
+uninstall-cilkincludeHEADERS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(cilkinclude_HEADERS)'; test -n "$(cilkincludedir)" || list=; \
+       files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+       test -n "$$files" || exit 0; \
+       echo " ( cd '$(DESTDIR)$(cilkincludedir)' && rm -f" $$files ")"; \
+       cd "$(DESTDIR)$(cilkincludedir)" && rm -f $$files
+
+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; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
+       mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       set x; \
+       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; }; }'`; \
+       shift; \
+       if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+         test -n "$$unique" || unique=$$empty_fix; \
+         if test $$# -gt 0; then \
+           $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+             "$$@" $$unique; \
+         else \
+           $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+             $$unique; \
+         fi; \
+       fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       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)$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && $(am__cd) $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) all-multi $(HEADERS)
+installdirs:
+       for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(cilkincludedir)"; 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)
+       -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-multi
+
+clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \
+       mostlyclean-am
+
+distclean: distclean-am distclean-multi
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-cilkincludeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-multi install-toolexeclibLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am maintainer-clean-multi
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+       -rm -rf $(top_srcdir)/autom4te.cache
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am mostlyclean-multi
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-cilkincludeHEADERS \
+       uninstall-toolexeclibLTLIBRARIES
+
+.MAKE: all-multi clean-multi distclean-multi install-am install-multi \
+       install-strip maintainer-clean-multi mostlyclean-multi
+
+.PHONY: CTAGS GTAGS all all-am all-multi am--refresh check check-am \
+       clean clean-generic clean-libtool clean-multi \
+       clean-toolexeclibLTLIBRARIES ctags distclean distclean-compile \
+       distclean-generic distclean-libtool distclean-multi \
+       distclean-tags dvi dvi-am html html-am info info-am install \
+       install-am install-cilkincludeHEADERS install-data \
+       install-data-am install-dvi install-dvi-am install-exec \
+       install-exec-am install-html install-html-am install-info \
+       install-info-am install-man install-multi install-pdf \
+       install-pdf-am install-ps install-ps-am install-strip \
+       install-toolexeclibLTLIBRARIES installcheck installcheck-am \
+       installdirs maintainer-clean maintainer-clean-generic \
+       maintainer-clean-multi mostlyclean mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool mostlyclean-multi pdf \
+       pdf-am ps ps-am tags uninstall uninstall-am \
+       uninstall-cilkincludeHEADERS uninstall-toolexeclibLTLIBRARIES
+
+
+# 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/libcilkrts/README b/libcilkrts/README
new file mode 100644 (file)
index 0000000..7c10115
--- /dev/null
@@ -0,0 +1,84 @@
+Intel(R) Cilk(TM) Plus runtime library
+
+Index:
+1. BUILDING
+2. USING
+3. DOXYGEN DOCUMENTATION
+4. QUESTIONS OR BUGS
+5. CONTRIBUTIONS
+
+#
+#  1. BUILDING:
+#
+
+To distribute applications that use the Intel Cilk Plus language
+extensions to non-development systems, you need to build the Intel
+Cilk Plus runtime library and distribute it with your application.
+
+To build the libcilkrts.so runtime library component, you need the
+autoconf and automake packages, which are available through your
+favorite package manager.  You also need a C/C++ compiler that
+supports the Intel Cilk Plus language extensions, since the runtime
+uses Intel Cilk Plus features internally.  Use either the Intel(R)
+C++ Compiler (icc command) v12.1 or later, or in GCC 4.9 or later
+(gcc command).
+
+Once you have the necessary prerequisites installed, you can use the
+following commands to create the library:
+
+% libtoolize
+% aclocal
+% automake --add-missing
+% autoconf
+% ./configure
+% make
+% make install
+
+This will produce the libcilkrts.so shared object.  To install the
+library in a custom location, set the prefix while running the
+configure script:
+
+% ./configure --prefix=/your/path/to/lib
+
+#
+#  2. USING:
+#
+
+The Intel(R) C++ Compiler will automatically try to bring in the
+Intel Cilk Plus runtime in any program that uses the relevant
+features.  GCC requires explicit linking of both the library and
+its dependencies (libpthread, libdl).  For example:
+
+% gcc foo.c -lcilkrts -lpthread -ldl
+
+#
+#  3. DOXYGEN DOCUMENTATION:
+#
+
+The library source has Doxygen markup.  Generate HTML documentation
+based on the markup by changing directory into runtime and running:
+
+% doxygen doxygen.cfg
+
+#
+#  4. QUESTIONS OR BUGS:
+#
+
+Issues with the Intel Cilk Plus runtime can be addressed in the Intel
+Cilk Plus forums:
+http://software.intel.com/en-us/forums/intel-cilk-plus/
+
+#
+#  5. CONTRIBUTIONS:
+#
+
+The Intel Cilk Plus runtime library is dual licensed. The upstream copy
+of the library is maintained via the BSD-licensed version available at:
+http://cilkplus.org/
+
+Changes to the Intel Cilk Plus runtime are welcome and should be
+contributed to the upstream version via http://cilkplus.org/.
+
+------------------------
+Intel and Cilk are trademarks of Intel Corporation in the U.S. and/or
+other countries.
diff --git a/libcilkrts/aclocal.m4 b/libcilkrts/aclocal.m4
new file mode 100644 (file)
index 0000000..446bede
--- /dev/null
@@ -0,0 +1,939 @@
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+# This file 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.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,
+[m4_warning([this file was generated for autoconf 2.64.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version.  Point them to the right macro.
+m4_if([$1], [1.11.1], [],
+      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too.  Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file 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.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+       [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 10
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
+       [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+       [$1], UPC,  [depcc="$UPC"  am_compiler_list=],
+       [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                   [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  am__universal=false
+  m4_case([$1], [CC],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac],
+    [CXX],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac])
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+       continue
+      else
+       break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named `Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`AS_DIRNAME("$mf")`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running `make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # When using ansi2knr, U may be empty or an underscore; expand it
+    U=`sed -n 's/^U = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`AS_DIRNAME(["$file"])`
+      AS_MKDIR_P([$dirpart/$fdir])
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 16
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+             [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+                            [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+                 [_AM_DEPENDENCIES(CC)],
+                 [define([AC_PROG_CC],
+                         defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+                 [_AM_DEPENDENCIES(CXX)],
+                 [define([AC_PROG_CXX],
+                         defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+                 [_AM_DEPENDENCIES(OBJC)],
+                 [define([AC_PROG_OBJC],
+                         defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\    *)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+AC_SUBST(install_sh)])
+
+# Check to see how 'make' treats includes.                 -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009  Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+       @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\    *)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p.  We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+  [[\\/$]]* | ?:[[\\/]]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[[\\\"\#\$\&\'\`$am_lf]]*)
+    AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+  *[[\\\"\#\$\&\'\`$am_lf\ \   ]]*)
+    AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008  Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [m4_case([$1], [ustar],, [pax],,
+              [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+  case $_am_tool in
+  gnutar)
+    for _am_tar in tar gnutar gtar;
+    do
+      AM_RUN_LOG([$_am_tar --version]) && break
+    done
+    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+    am__untar="$_am_tar -xf -"
+    ;;
+  plaintar)
+    # Must skip GNU tar: if it does not support --format= it doesn't create
+    # ustar tarball either.
+    (tar --version) >/dev/null 2>&1 && continue
+    am__tar='tar chf - "$$tardir"'
+    am__tar_='tar chf - "$tardir"'
+    am__untar='tar xf -'
+    ;;
+  pax)
+    am__tar='pax -L -x $1 -w "$$tardir"'
+    am__tar_='pax -L -x $1 -w "$tardir"'
+    am__untar='pax -r'
+    ;;
+  cpio)
+    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+    am__untar='cpio -i -H $1 -d'
+    ;;
+  none)
+    am__tar=false
+    am__tar_=false
+    am__untar=false
+    ;;
+  esac
+
+  # If the value was cached, stop now.  We just wanted to have am__tar
+  # and am__untar set.
+  test -n "${am_cv_prog_tar_$1}" && break
+
+  # tar/untar a dummy directory, and stop if the command works
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  echo GrepMe > conftest.dir/file
+  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+  rm -rf conftest.dir
+  if test -s conftest.tar; then
+    AM_RUN_LOG([$am__untar <conftest.tar])
+    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+  fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([../config/depstand.m4])
+m4_include([../config/lead-dot.m4])
+m4_include([../config/multi.m4])
+m4_include([../config/override.m4])
+m4_include([../libtool.m4])
+m4_include([../ltoptions.m4])
+m4_include([../ltsugar.m4])
+m4_include([../ltversion.m4])
+m4_include([../lt~obsolete.m4])
diff --git a/libcilkrts/configure b/libcilkrts/configure
new file mode 100644 (file)
index 0000000..18fb408
--- /dev/null
@@ -0,0 +1,16649 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.64 for Cilk Runtime Library 2.0.
+#
+# Report bugs to <cilk@intel.com>.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
+# Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+       expr "X$arg" : "X\\(.*\\)$as_nl";
+       arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""       $as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+
+  test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+        /*)
+          for as_base in sh bash ksh sh5; do
+            # Try only shells that exist, to save several forks.
+            as_shell=$as_dir/$as_base
+            if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+                   { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+                  if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+          done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+             { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+       # neutralization value for shells without unset; and this also
+       # works around shells that cannot unset nonexistent variables.
+       BASH_ENV=/dev/null
+       ENV=/dev/null
+       (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+       export CONFIG_SHELL
+       exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf@gnu.org and cilk@intel.com
+$0: about your system, including any error possibly output
+$0: before this message. Then install a modern shell, or
+$0: manually run the script under such a shell if you do
+$0: have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='        ';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+       test -d "$1/.";
+      else
+       case $1 in #(
+       -*)set "./$1";;
+       esac;
+       case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+       ???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='Cilk Runtime Library'
+PACKAGE_TARNAME='cilk-runtime-library'
+PACKAGE_VERSION='2.0'
+PACKAGE_STRING='Cilk Runtime Library 2.0'
+PACKAGE_BUGREPORT='cilk@intel.com'
+PACKAGE_URL=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+toolexeclibdir
+toolexecdir
+CXXCPP
+CPP
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+RANLIB
+AR
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+LIBTOOL
+MAC_LINKER_SCRIPT_FALSE
+MAC_LINKER_SCRIPT_TRUE
+LINUX_LINKER_SCRIPT_FALSE
+LINUX_LINKER_SCRIPT_TRUE
+config_dir
+multi_basedir
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+ac_ct_CC
+CFLAGS
+CC
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CXX
+CPPFLAGS
+LDFLAGS
+CXXFLAGS
+CXX
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_os
+target_vendor
+target_cpu
+target
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_dependency_tracking
+enable_multilib
+enable_version_specific_runtime_libs
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+enable_libtool_lock
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CXX
+CXXFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CCC
+CC
+CFLAGS
+CPP
+CXXCPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *)   ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+        ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+        ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+        ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+        ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
+               datadir sysconfdir sharedstatedir localstatedir includedir \
+               oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+               libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_myself" : 'X\(//\)[^/]' \| \
+        X"$as_myself" : 'X\(//\)$' \| \
+        X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+       cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+       pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures Cilk Runtime Library 2.0 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root
+                          [DATAROOTDIR/doc/cilk-runtime-library]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of Cilk Runtime Library 2.0:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors
+  --enable-multilib       build many library versions (default)
+  --enable-version-specific-runtime-libs
+                          Specify that runtime libraries should be installed
+                          in a compi ler-specific directory
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-static[=PKGS]  build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pic              try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+
+Some influential environment variables:
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  CPP         C preprocessor
+  CXXCPP      C++ preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <cilk@intel.com>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+Cilk Runtime Library configure 2.0
+generated by GNU Autoconf 2.64
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+        test -z "$ac_cxx_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+        test "$cross_compiling" = yes ||
+        $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } >/dev/null && {
+        test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+        test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+        test -z "$ac_cxx_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+        test "$cross_compiling" = yes ||
+        $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_cxx_try_link
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by Cilk Runtime Library $as_me 2.0, which was
+generated by GNU Autoconf 2.64.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+       ac_must_keep_next=false # Got value, back to normal.
+      else
+       case $ac_arg in
+         *=* | --config-cache | -C | -disable-* | --disable-* \
+         | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+         | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+         | -with-* | --with-* | -without-* | --without-* | --x)
+           case "$ac_configure_args0 " in
+             "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+           esac
+           ;;
+         -* ) ac_must_keep_next=true ;;
+       esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+       "s/'\''/'\''\\\\'\'''\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=\$$ac_var
+       case $ac_val in
+       *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+       esac
+       $as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       # differences in whitespace do not lead to failure.
+       ac_old_val_w=`echo x $ac_old_val`
+       ac_new_val_w=`echo x $ac_new_val`
+       if test "$ac_old_val_w" != "$ac_new_val_w"; then
+         { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+         ac_cache_corrupted=:
+       else
+         { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+         eval $ac_var=\$ac_old_val
+       fi
+       { $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+       { $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+# Needed to define ${target}.  Needs to be very early to avoid annoying
+# warning about calling AC_ARG_PROGRAM before AC_CANONICAL_SYSTEM
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  for ac_t in install-sh install.sh shtool; do
+    if test -f "$ac_dir/$ac_t"; then
+      ac_aux_dir=$ac_dir
+      ac_install_sh="$ac_aux_dir/$ac_t -c"
+      break 2
+    fi
+  done
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
+$as_echo_n "checking target system type... " >&6; }
+if test "${ac_cv_target+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$target_alias" = x; then
+  ac_cv_target=$ac_cv_host
+else
+  ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
+    as_fn_error "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
+$as_echo "$ac_cv_target" >&6; }
+case $ac_cv_target in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical target" "$LINENO" 5;;
+esac
+target=$ac_cv_target
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_target
+shift
+target_cpu=$1
+target_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+target_os=$*
+IFS=$ac_save_IFS
+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+am__api_version='1.11'
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+       if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+         if test $ac_prog = install &&
+           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           rm -rf conftest.one conftest.two conftest.dir
+           echo one > conftest.one
+           echo two > conftest.two
+           mkdir conftest.dir
+           if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+             test -s conftest.one && test -s conftest.two &&
+             test -s conftest.dir/conftest.one &&
+             test -s conftest.dir/conftest.two
+           then
+             ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+             break 3
+           fi
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[\\\"\#\$\&\'\`$am_lf]*)
+    as_fn_error "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+  *[\\\"\#\$\&\'\`$am_lf\ \    ]*)
+    as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      as_fn_error "ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   as_fn_error "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\    *)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\    *)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if test "${ac_cv_path_mkdir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in mkdir gmkdir; do
+        for ac_exec_ext in '' $ac_executable_extensions; do
+          { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+          case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+            'mkdir (GNU coreutils) '* | \
+            'mkdir (coreutils) '* | \
+            'mkdir (fileutils) '4.1*)
+              ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+              break 3;;
+          esac
+        done
+       done
+  done
+IFS=$as_save_IFS
+
+fi
+
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    test -d ./--version && rmdir ./--version
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+  [\\/$]* | ?:[\\/]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+       @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='cilk-runtime-library'
+ VERSION='2.0'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+# Build a DLL on Windows
+# AC_LIBTOOL_WIN32_DLL
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    rm -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5
+$as_echo_n "checking for C++ compiler default output file name... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+       if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+       then :; else
+          ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       fi
+       # We set ac_cv_exeext here because the later test for it is not
+       # safe: cross compilers may not add the suffix if given an `-o'
+       # argument, so we may need to know it at that point already.
+       # Even if this section looks crufty: it has the advantage of
+       # actually working.
+       break;;
+    * )
+       break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+if test -z "$ac_file"; then :
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "C++ compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
+fi
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5
+$as_echo_n "checking whether the C++ compiler works... " >&6; }
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+        CXXFLAGS="-g"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+       @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+depcc="$CXX"  am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CXX_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+       continue
+      else
+       break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    rm -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+        CFLAGS="-g"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+       -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+       continue
+      else
+       break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+# AC_PROG_LIBTOOL
+# AC_CONFIG_MACRO_DIR([..])
+ac_config_files="$ac_config_files Makefile"
+
+# Default to --enable-multilib
+# Check whether --enable-multilib was given.
+if test "${enable_multilib+set}" = set; then :
+  enableval=$enable_multilib; case "$enableval" in
+  yes) multilib=yes ;;
+  no)  multilib=no ;;
+  *)   as_fn_error "bad value $enableval for multilib option" "$LINENO" 5 ;;
+ esac
+else
+  multilib=yes
+fi
+
+
+# We may get other options which we leave undocumented:
+# --with-target-subdir, --with-multisrctop, --with-multisubdir
+# See config-ml.in if you want the gory details.
+
+if test "$srcdir" = "."; then
+  if test "$with_target_subdir" != "."; then
+    multi_basedir="$srcdir/$with_multisrctop../.."
+  else
+    multi_basedir="$srcdir/$with_multisrctop.."
+  fi
+else
+  multi_basedir="$srcdir/.."
+fi
+
+
+# Even if the default multilib is not a cross compilation,
+# it may be that some of the other multilibs are.
+if test $cross_compiling = no && test $multilib = yes \
+   && test "x${with_multisubdir}" != x ; then
+   cross_compiling=maybe
+fi
+
+ac_config_commands="$ac_config_commands default-1"
+
+
+# Get target configury.
+. ${srcdir}/configure.tgt
+if test -n "$UNSUPPORTED"; then
+   as_fn_error "Configuration ${target} is unsupported." "$LINENO" 5
+fi
+
+if test "${multilib}" = "yes"; then
+  multilib_arg="--enable-multilib"
+else
+  multilib_arg=
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-version-specific-runtime-libs" >&5
+$as_echo_n "checking for --enable-version-specific-runtime-libs... " >&6; }
+# Check whether --enable-version-specific-runtime-libs was given.
+if test "${enable_version_specific_runtime_libs+set}" = set; then :
+  enableval=$enable_version_specific_runtime_libs; case "$enableval" in
+    yes) enable_version_specific_runtime_libs=yes ;;
+    no)  enable_version_specific_runtime_libs=no ;;
+    *)   as_fn_error "Unknown argument to enable/disable version-specific libs
+" "$LINENO" 5;;
+   esac
+else
+  enable_version_specific_runtime_libs=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_version_specific_runtime_libs" >&5
+$as_echo "$enable_version_specific_runtime_libs" >&6; }
+
+
+# Calculate toolexeclibdir
+# Also toolexecdir, though it's only used in toolexeclibdir
+case ${enable_version_specific_runtime_libs} in
+  yes)
+    # Need the gcc compiler version to know where to install libraries
+    # and header files if --enable-version-specific-runtime-libs option
+    # is selected.
+    toolexecdir='$(libdir)/gcc/$(target_alias)'
+   toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
+    ;;
+  no)
+    if test -n "$with_cross_host" &&
+       test x"$with_cross_host" != x"no"; then
+      # Install a library built with a cross compiler in tooldir, not libdir.
+      toolexecdir='$(exec_prefix)/$(target_alias)'
+      toolexeclibdir='$(toolexecdir)/lib'
+    else
+      toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
+      toolexeclibdir='$(libdir)'
+    fi
+    multi_os_directory=`$CC -print-multi-os-directory`
+    case $multi_os_directory in
+      .) ;; # Avoid trailing /.
+      *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+    esac
+    ;;
+esac
+
+# Set config_dir based on the target.  config_dir specifies where to get
+# target-specific files.  The generic implementation is incomplete, but
+# contains information on what's needed
+case "${target}" in
+
+  x86_64-*-*)
+    config_dir="x86"
+    ;;
+
+  i45686-*-*)
+    config_dir="x86"
+    ;;
+
+  *)
+    config_dir="generic"
+    ;;
+
+esac
+
+
+# We have linker scripts for appropriate operating systems
+linux_linker_script=no
+case "${host}" in
+    *-*-linux*)
+        linux_linker_script=yes
+        ;;
+esac
+ if test "$linux_linker_script" = "yes"; then
+  LINUX_LINKER_SCRIPT_TRUE=
+  LINUX_LINKER_SCRIPT_FALSE='#'
+else
+  LINUX_LINKER_SCRIPT_TRUE='#'
+  LINUX_LINKER_SCRIPT_FALSE=
+fi
+
+
+mac_linker_script=no
+case "${host}" in
+    *-*-apple*)
+        mac_linker_script=yes
+        ;;
+esac
+ if test "$mac_linker_script" = "yes"; then
+  MAC_LINKER_SCRIPT_TRUE=
+  MAC_LINKER_SCRIPT_FALSE='#'
+else
+  MAC_LINKER_SCRIPT_TRUE='#'
+  MAC_LINKER_SCRIPT_FALSE=
+fi
+
+
+case `pwd` in
+  *\ * | *\    *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.2.7a'
+macro_revision='1.3134'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`print -r -- -n 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if test "${ac_cv_path_SED+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+# Check for GNU ac_path_SED and select it if it is found.
+  # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo '' >> "conftest.nl"
+    "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_SED_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_SED="$ac_path_SED"
+      ac_path_SED_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_SED_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_SED"; then
+    as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5
+  fi
+else
+  ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+  rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if test "${ac_cv_path_FGREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+   then ac_cv_path_FGREP="$GREP -F"
+   else
+     if test -z "$FGREP"; then
+  ac_path_FGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in fgrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+  # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'FGREP' >> "conftest.nl"
+    "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_FGREP="$ac_path_FGREP"
+      ac_path_FGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_FGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_FGREP"; then
+    as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_FGREP=$FGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+       test "$with_gnu_ld" != no && break
+       ;;
+      *)
+       test "$with_gnu_ld" != yes && break
+       ;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if test "${lt_cv_path_NM+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+       # Check to see if the nm accepts a BSD-compat flag.
+       # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+       #   nm: unknown option "B" ignored
+       # Tru64's nm complains that /dev/null is an invalid object file
+       case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+       */dev/null* | *'Invalid file or object type'*)
+         lt_cv_path_NM="$tmp_nm -B"
+         break
+         ;;
+       *)
+         case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+         */dev/null*)
+           lt_cv_path_NM="$tmp_nm -p"
+           break
+           ;;
+         *)
+           lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+           continue # so that we can try to find one that supports BSD flags
+           ;;
+         esac
+         ;;
+       esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DUMPBIN"; then
+  ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$DUMPBIN" && break
+  done
+fi
+if test -z "$DUMPBIN"; then
+  ac_ct_DUMPBIN=$DUMPBIN
+  for ac_prog in dumpbin "link -dump"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DUMPBIN"; then
+  ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_DUMPBIN" && break
+done
+
+  if test "x$ac_ct_DUMPBIN" = x; then
+    DUMPBIN=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DUMPBIN=$ac_ct_DUMPBIN
+  fi
+fi
+
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if test "${lt_cv_nm_interface+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+  cat conftest.out >&5
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+    i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536      # usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[         ]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \
+                = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+             test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if test "${lt_cv_ld_reload_flag+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OBJDUMP="objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if test "${lt_cv_deplibs_check_method+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[3-9]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AR+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AR="${ac_tool_prefix}ar"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+  ac_ct_AR=$AR
+  # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_AR="ar"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+else
+  AR="$ac_cv_prog_AR"
+fi
+
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDEGRST]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris*)
+  symcode='[BDRT]'
+  ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK '"\
+"     {last_section=section; section=\$ 3};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[     ]\($symcode$symcode*\)[         ][      ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+       mv -f "$nlist"T "$nlist"
+      else
+       rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+       if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+         cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+         # Now generate the symbol file.
+         eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+         cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+const struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+         $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+         cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+         # Now try linking the two files.
+         mv conftest.$ac_objext conftstm.$ac_objext
+         lt_save_LIBS="$LIBS"
+         lt_save_CFLAGS="$CFLAGS"
+         LIBS="conftstm.$ac_objext"
+         CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+         if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+           pipe_works=yes
+         fi
+         LIBS="$lt_save_LIBS"
+         CFLAGS="$lt_save_CFLAGS"
+       else
+         echo "cannot find nm_test_func in $nlist" >&5
+       fi
+      else
+       echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+  enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+       HPUX_IA64_MODE="32"
+       ;;
+      *ELF-64*)
+       HPUX_IA64_MODE="64"
+       ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+       *32-bit*)
+         LD="${LD-ld} -melf32bsmip"
+         ;;
+       *N32*)
+         LD="${LD-ld} -melf32bmipn32"
+         ;;
+       *64-bit*)
+         LD="${LD-ld} -melf64bmip"
+       ;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+       *32-bit*)
+         LD="${LD-ld} -32"
+         ;;
+       *N32*)
+         LD="${LD-ld} -n32"
+         ;;
+       *64-bit*)
+         LD="${LD-ld} -64"
+         ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+       case $host in
+         x86_64-*kfreebsd*-gnu)
+           LD="${LD-ld} -m elf_i386_fbsd"
+           ;;
+         x86_64-*linux*)
+           case `/usr/bin/file conftest.o` in
+             *x86-64*)
+               LD="${LD-ld} -m elf32_x86_64"
+               ;;
+             *)
+               LD="${LD-ld} -m elf_i386"
+               ;;
+           esac
+           ;;
+         powerpc64le-*linux*)
+           LD="${LD-ld} -m elf32lppclinux"
+           ;;
+         powerpc64-*linux*)
+           LD="${LD-ld} -m elf32ppclinux"
+           ;;
+         s390x-*linux*)
+           LD="${LD-ld} -m elf_s390"
+           ;;
+         sparc64-*linux*)
+           LD="${LD-ld} -m elf32_sparc"
+           ;;
+       esac
+       ;;
+      *64-bit*)
+       case $host in
+         x86_64-*kfreebsd*-gnu)
+           LD="${LD-ld} -m elf_x86_64_fbsd"
+           ;;
+         x86_64-*linux*)
+           LD="${LD-ld} -m elf_x86_64"
+           ;;
+         powerpcle-*linux*)
+           LD="${LD-ld} -m elf64lppc"
+           ;;
+         powerpc-*linux*)
+           LD="${LD-ld} -m elf64ppc"
+           ;;
+         s390*-*linux*|s390*-*tpf*)
+           LD="${LD-ld} -m elf64_s390"
+           ;;
+         sparc*-*linux*)
+           LD="${LD-ld} -m elf64_sparc"
+           ;;
+       esac
+       ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if test "${lt_cv_cc_needs_belf+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_cc_needs_belf=yes
+else
+  lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)
+       if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+         LD="${LD-ld} -64"
+       fi
+       ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+
+  case $host_os in
+    rhapsody* | darwin*)
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DSYMUTIL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DSYMUTIL"; then
+  ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+  ac_ct_DSYMUTIL=$DSYMUTIL
+  # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DSYMUTIL"; then
+  ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DSYMUTIL" = x; then
+    DSYMUTIL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DSYMUTIL=$ac_ct_DSYMUTIL
+  fi
+else
+  DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_NMEDIT+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NMEDIT"; then
+  ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+  ac_ct_NMEDIT=$NMEDIT
+  # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_NMEDIT"; then
+  ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_NMEDIT="nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_NMEDIT" = x; then
+    NMEDIT=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    NMEDIT=$ac_ct_NMEDIT
+  fi
+else
+  NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_LIPO+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LIPO"; then
+  ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+  ac_ct_LIPO=$LIPO
+  # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_LIPO"; then
+  ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_LIPO="lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_LIPO" = x; then
+    LIPO=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    LIPO=$ac_ct_LIPO
+  fi
+else
+  LIPO="$ac_cv_prog_LIPO"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL"; then
+  ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+  ac_ct_OTOOL=$OTOOL
+  # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL"; then
+  ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OTOOL="otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL" = x; then
+    OTOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL=$ac_ct_OTOOL
+  fi
+else
+  OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL64+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL64"; then
+  ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+  ac_ct_OTOOL64=$OTOOL64
+  # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL64"; then
+  ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OTOOL64="otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL64" = x; then
+    OTOOL64=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL64=$ac_ct_OTOOL64
+  fi
+else
+  OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if test "${lt_cv_apple_cc_single_mod+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+       # By default we will add the -single_module flag. You can override
+       # by either setting the environment variable LT_MULTI_MODULE
+       # non-empty at configure time, or by adding -multi_module to the
+       # link flags.
+       rm -rf libconftest.dylib*
+       echo "int foo(void){return 1;}" > conftest.c
+       echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+       $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+         -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+       if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+         lt_cv_apple_cc_single_mod=yes
+       else
+         cat conftest.err >&5
+       fi
+       rm -rf libconftest.dylib*
+       rm -f conftest.*
+      fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if test "${lt_cv_ld_exported_symbols_list+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_ld_exported_symbols_list=yes
+else
+  lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+       LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if test "${lt_cv_ld_force_load+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then
+       lt_cv_ld_force_load=yes
+      else
+       cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+    case $host_os in
+    rhapsody* | darwin1.[012])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+       10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+         _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+       10.[012]*)
+         _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+       10.*)
+         _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=no
+
+
+            # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_shared=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+  # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+  enableval=$enable_static; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_static=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+  withval=$with_pic; pic_mode="$withval"
+else
+  pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+  # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+  enableval=$enable_fast_install; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_fast_install=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if test "${lt_cv_objdir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+       case $deplibs_check_method in
+       "file_magic "*)
+         file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+           $EGREP "$file_magic_regex" > /dev/null; then
+           :
+         else
+           cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+         fi ;;
+       esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+       case $deplibs_check_method in
+       "file_magic "*)
+         file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+           $EGREP "$file_magic_regex" > /dev/null; then
+           :
+         else
+           cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+         fi ;;
+       esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+
+
+
+
+
+  lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static='-Bstatic'
+      fi
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic='-fPIC'
+       ;;
+      esac
+      ;;
+
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      lt_prog_compiler_pic='-Xcompiler -fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static='-Bstatic'
+      else
+       lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic='+Z'
+       ;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+       lt_prog_compiler_wl='-Wl,'
+       lt_prog_compiler_pic='-KPIC'
+       lt_prog_compiler_static='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+       lt_prog_compiler_wl='-Wl,'
+       lt_prog_compiler_pic='-fPIC'
+       lt_prog_compiler_static='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+       lt_prog_compiler_wl='-Wl,'
+       lt_prog_compiler_pic='--shared'
+       lt_prog_compiler_static='--static'
+       ;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+       # which looks to be a dead project)
+       lt_prog_compiler_wl='-Wl,'
+       lt_prog_compiler_pic='-fpic'
+       lt_prog_compiler_static='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+       # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+       lt_prog_compiler_wl='-Wl,'
+       lt_prog_compiler_pic='-qpic'
+       lt_prog_compiler_static='-qstaticlink'
+       ;;
+      *)
+       case `$CC -V 2>&1 | sed 5q` in
+       *Sun\ F* | *Sun*Fortran*)
+         # Sun Fortran 8.3 passes all unrecognized flags to the linker
+         lt_prog_compiler_pic='-KPIC'
+         lt_prog_compiler_static='-Bstatic'
+         lt_prog_compiler_wl=''
+         ;;
+       *Sun\ C*)
+         # Sun C 5.9
+         lt_prog_compiler_pic='-KPIC'
+         lt_prog_compiler_static='-Bstatic'
+         lt_prog_compiler_wl='-Wl,'
+         ;;
+       esac
+       ;;
+      esac
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    rdos*)
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+       lt_prog_compiler_wl='-Qoption ld ';;
+      *)
+       lt_prog_compiler_wl='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+       lt_prog_compiler_pic='-Kconform_pic'
+       lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_can_build_shared=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+$as_echo "$lt_prog_compiler_pic" >&6; }
+
+
+
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  runpath_var=
+  allow_undefined_flag=
+  always_export_symbols=no
+  archive_cmds=
+  archive_expsym_cmds=
+  compiler_needs_object=no
+  enable_shared_with_static_runtimes=no
+  export_dynamic_flag_spec=
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  hardcode_automatic=no
+  hardcode_direct=no
+  hardcode_direct_absolute=no
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_flag_spec_ld=
+  hardcode_libdir_separator=
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  inherit_rpath=no
+  link_all_deplibs=unknown
+  module_cmds=
+  module_expsym_cmds=
+  old_archive_from_new_cmds=
+  old_archive_from_expsyms_cmds=
+  thread_safe_flag_spec=
+  whole_archive_flag_spec=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+       # The AIX port of GNU ld has always aspired to compatibility
+       # with the native linker.  However, as the warning in the GNU ld
+       # block says, versions before 2.19.5* couldn't really create working
+       # shared libraries, regardless of the interface used.
+       case `$LD -v 2>&1` in
+         *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+         *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+         *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+         *)
+           lt_use_gnu_ld_interface=yes
+           ;;
+       esac
+       ;;
+      *)
+       lt_use_gnu_ld_interface=yes
+       ;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[3-9]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+       ld_shlibs=no
+       cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+       allow_undefined_flag=unsupported
+       # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+       # support --undefined.  This deserves some investigation.  FIXME
+       archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+       # If the export-symbols file already is a .def file (1st line
+       # is EXPORTS), use it as is; otherwise, prepend...
+       archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+         cp $export_symbols $output_objdir/$soname.def;
+       else
+         echo EXPORTS > $output_objdir/$soname.def;
+         cat $export_symbols >> $output_objdir/$soname.def;
+       fi~
+       $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+       case $cc_basename in
+         diet\ *) tmp_diet=yes;;       # linux-dietlibc with static linking (!diet-dyn)
+       esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+        && test "$tmp_diet" = no
+      then
+       tmp_addflag=
+       tmp_sharedflag='-shared'
+       case $cc_basename,$host_cpu in
+        pgcc*)                         # Portland Group C compiler
+         whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+         tmp_addflag=' $pic_flag'
+         ;;
+       pgf77* | pgf90* | pgf95* | pgfortran*)
+                                       # Portland Group f77 and f90 compilers
+         whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+         tmp_addflag=' $pic_flag -Mnomain' ;;
+       ecc*,ia64* | icc*,ia64*)        # Intel C compiler on ia64
+         tmp_addflag=' -i_dynamic' ;;
+       efc*,ia64* | ifort*,ia64*)      # Intel Fortran compiler on ia64
+         tmp_addflag=' -i_dynamic -nofor_main' ;;
+       ifc* | ifort*)                  # Intel Fortran compiler
+         tmp_addflag=' -nofor_main' ;;
+       lf95*)                          # Lahey Fortran 8.1
+         whole_archive_flag_spec=
+         tmp_sharedflag='--shared' ;;
+       xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+         tmp_sharedflag='-qmkshrobj'
+         tmp_addflag= ;;
+       nvcc*)  # Cuda Compiler Driver 2.2
+         whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+         compiler_needs_object=yes
+         ;;
+       esac
+       case `$CC -V 2>&1 | sed 5q` in
+       *Sun\ C*)                       # Sun C 5.9
+         whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+         compiler_needs_object=yes
+         tmp_sharedflag='-G' ;;
+       *Sun\ F*)                       # Sun Fortran 8.3
+         tmp_sharedflag='-G' ;;
+       esac
+       archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+           cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+           echo "local: *; };" >> $output_objdir/$libname.ver~
+           $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+       case $cc_basename in
+       xlf* | bgf* | bgxlf* | mpixlf*)
+         # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+         whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+         hardcode_libdir_flag_spec=
+         hardcode_libdir_flag_spec_ld='-rpath $libdir'
+         archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+         if test "x$supports_anon_versioning" = xyes; then
+           archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+             cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+             echo "local: *; };" >> $output_objdir/$libname.ver~
+             $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+         fi
+         ;;
+       esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+       archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+       wlarc=
+      else
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+       ld_shlibs=no
+       cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+       ld_shlibs=no
+       cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+       ;;
+       *)
+         # For security reasons, it is highly recommended that you always
+         # use absolute paths for naming shared libraries, and exclude the
+         # DT_RUNPATH tag from executables and libraries.  But doing so
+         # requires that you compile everything twice, which is a pain.
+         if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+           hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+           archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+           archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+         else
+           ld_shlibs=no
+         fi
+       ;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec=
+      export_dynamic_flag_spec=
+      whole_archive_flag_spec=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+       # Neither direct hardcoding nor static linking is supported with a
+       # broken collect2.
+       hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix[4-9]*)
+      if test "$host_cpu" = ia64; then
+       # On IA64, the linker does run time linking by default, so we don't
+       # have to do anything special.
+       aix_use_runtimelinking=no
+       exp_sym_flag='-Bexport'
+       no_entry_flag=""
+      else
+       # If we're using GNU nm, then we don't want the "-C" option.
+       # -C means demangle to AIX nm, but means don't demangle with GNU nm
+       # Also, AIX nm treats weak defined symbols like other global
+       # defined symbols, whereas GNU nm marks them as "W".
+       if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+         export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+       else
+         export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+       fi
+       aix_use_runtimelinking=no
+
+       # Test if we are trying to use run time linking or normal
+       # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+       # need to do runtime linking.
+       case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+         for ld_flag in $LDFLAGS; do
+         if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+           aix_use_runtimelinking=yes
+           break
+         fi
+         done
+         ;;
+       esac
+
+       exp_sym_flag='-bexport'
+       no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_direct_absolute=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      file_list_spec='${wl}-f,'
+
+      if test "$GCC" = yes; then
+       case $host_os in aix4.[012]|aix4.[012].*)
+       # We only want to do this on AIX 4.2 and lower, the check
+       # below for broken collect2 doesn't work under 4.3+
+         collect2name=`${CC} -print-prog-name=collect2`
+         if test -f "$collect2name" &&
+          strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+         then
+         # We have reworked collect2
+         :
+         else
+         # We have old collect2
+         hardcode_direct=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         hardcode_minus_L=yes
+         hardcode_libdir_flag_spec='-L$libdir'
+         hardcode_libdir_separator=
+         fi
+         ;;
+       esac
+       shared_flag='-shared'
+       if test "$aix_use_runtimelinking" = yes; then
+         shared_flag="$shared_flag "'${wl}-G'
+       fi
+      else
+       # not using gcc
+       if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+         shared_flag='-G'
+       else
+         if test "$aix_use_runtimelinking" = yes; then
+           shared_flag='${wl}-G'
+         else
+           shared_flag='${wl}-bM:SRE'
+         fi
+       fi
+      fi
+
+      export_dynamic_flag_spec='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test "$aix_use_runtimelinking" = yes; then
+       # Warning - without using the other runtime loading flags (-brtl),
+       # -berok will link without error, but may produce a broken library.
+       allow_undefined_flag='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+       /^0/ {
+           s/^0  *\(.*\)$/\1/
+           p
+       }
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+       if test "$host_cpu" = ia64; then
+         hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+         allow_undefined_flag="-z nodefs"
+         archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+       else
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+       /^0/ {
+           s/^0  *\(.*\)$/\1/
+           p
+       }
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+         # Warning - without using the other run time loading flags,
+         # -berok will link without error, but may produce a broken library.
+         no_undefined_flag=' ${wl}-bernotok'
+         allow_undefined_flag=' ${wl}-berok'
+         if test "$with_gnu_ld" = yes; then
+           # We only use this code for GNU lds that support --whole-archive.
+           whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+         else
+           # Exported symbols can be pulled into shared objects from archives
+           whole_archive_flag_spec='$convenience'
+         fi
+         archive_cmds_need_lc=yes
+         # This is similar to how AIX traditionally builds its shared libraries.
+         archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+       fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec=' '
+      allow_undefined_flag=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_from_new_cmds='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes=yes
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  else
+    whole_archive_flag_spec=''
+  fi
+  link_all_deplibs=yes
+  allow_undefined_flag="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+  else
+  ld_shlibs=no
+  fi
+
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2.*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+       archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+       archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+       archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+       hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+       hardcode_libdir_flag_spec_ld='+b $libdir'
+       hardcode_libdir_separator=:
+       hardcode_direct=yes
+       hardcode_direct_absolute=yes
+       export_dynamic_flag_spec='${wl}-E'
+       # hardcode_minus_L: Not really in the search PATH,
+       # but as the default location of the library.
+       hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+       case $host_cpu in
+       hppa*64*)
+         archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       ia64*)
+         archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      else
+       case $host_cpu in
+       hppa*64*)
+         archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       ia64*)
+         archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+
+         # Older versions of the 11.00 compiler do not understand -b yet
+         # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+         { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if test "${lt_cv_prog_compiler__b+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS -b"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+    archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+         ;;
+       esac
+      fi
+      if test "$with_gnu_ld" = no; then
+       hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+       hardcode_libdir_separator=:
+
+       case $host_cpu in
+       hppa*64*|ia64*)
+         hardcode_direct=no
+         hardcode_shlibpath_var=no
+         ;;
+       *)
+         hardcode_direct=yes
+         hardcode_direct_absolute=yes
+         export_dynamic_flag_spec='${wl}-E'
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         hardcode_minus_L=yes
+         ;;
+       esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       # Try to use the -exported_symbol ld option, if it does not
+       # work, assume that -exports_file does not work either and
+       # implicitly export all symbols.
+        save_LDFLAGS="$LDFLAGS"
+        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo(void) {}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        LDFLAGS="$save_LDFLAGS"
+      else
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      inherit_rpath=yes
+      link_all_deplibs=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+       archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+       archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+       hardcode_direct=yes
+       hardcode_shlibpath_var=no
+       hardcode_direct_absolute=yes
+       if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+         archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+         archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+         hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+         export_dynamic_flag_spec='${wl}-E'
+       else
+         case $host_os in
+          openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+            archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+            hardcode_libdir_flag_spec='-R$libdir'
+            ;;
+          *)
+            archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+            hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+            ;;
+         esac
+       fi
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+       allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       allow_undefined_flag=' -expect_unresolved \*'
+       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)     # as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+       allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+       allow_undefined_flag=' -expect_unresolved \*'
+       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+       archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+       $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+       # Both c and cxx compiler support -rpath directly
+       hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_separator=:
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z defs'
+      if test "$GCC" = yes; then
+       wlarc='${wl}'
+       archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+         $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+       case `$CC -V 2>&1` in
+       *"Compilers 5.0"*)
+         wlarc=''
+         archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+         $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+         ;;
+       *)
+         wlarc='${wl}'
+         archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+         archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+         $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+         ;;
+       esac
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+       # The compiler driver will combine and reorder linker options,
+       # but understands `-z linker_flag'.  GCC discards it without `$wl',
+       # but is careful enough not to reorder.
+       # Supported since Solaris 2.6 (maybe 2.5.1?)
+       if test "$GCC" = yes; then
+         whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+       else
+         whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+       fi
+       ;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+       # Use $CC to link under sequent, because it throws in some extra .o
+       # files that make .init and .fini sections work.
+       archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+       sni)
+         archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct=yes # is this really true???
+       ;;
+       siemens)
+         ## LD is ld it makes a PLAMLIB
+         ## CC just makes a GrossModule.
+         archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+         reload_cmds='$CC -r -o $output$reload_objs'
+         hardcode_direct=no
+        ;;
+       motorola)
+         archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+       ;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       hardcode_shlibpath_var=no
+       runpath_var=LD_RUN_PATH
+       hardcode_runpath_var=yes
+       ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag='${wl}-z,text'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+       archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-R,$libdir'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+       archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+       export_dynamic_flag_spec='${wl}-Blargedynsym'
+       ;;
+      esac
+    fi
+  fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if test "${lt_cv_archive_cmds_need_lc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  $RM conftest*
+       echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+       if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+         soname=conftest
+         lib=conftest
+         libobjs=conftest.$ac_objext
+         deplibs=
+         wl=$lt_prog_compiler_wl
+         pic_flag=$lt_prog_compiler_pic
+         compiler_flags=-v
+         linker_flags=-v
+         verstring=
+         output_objdir=.
+         libname=conftest
+         lt_save_allow_undefined_flag=$allow_undefined_flag
+         allow_undefined_flag=
+         if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+         then
+           lt_cv_archive_cmds_need_lc=no
+         else
+           lt_cv_archive_cmds_need_lc=yes
+         fi
+         allow_undefined_flag=$lt_save_allow_undefined_flag
+       else
+         cat conftest.err 1>&5
+       fi
+       $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+       lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[lt_foo]++; }
+  if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+          echo ' yes '
+          echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+       :
+      else
+       can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+haiku*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+       if test "$lt_cv_prog_gnu_ld" = yes; then
+               version_type=linux
+       else
+               version_type=irix
+       fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+        LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[      ]*hwcap[        ]/d;s/[:,      ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+    *)                         need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+       shlibpath_overrides_runpath=no
+       ;;
+      *)
+       shlibpath_overrides_runpath=yes
+       ;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+       ;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+   test -n "$runpath_var" ||
+   test "X$hardcode_automatic" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+   test "$inherit_rpath" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+  if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+    ;;
+
+  *)
+    ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = x""yes; then :
+  lt_cv_dlopen="shl_load"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_svld_dlopen=yes
+else
+  ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_dld_link=yes
+else
+  ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+         if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line 10806 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+void fnord () __attribute__((visibility("default")));
+#endif
+
+void fnord () { int i=42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+         if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+       }
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self_static+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+         if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line 10912 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+void fnord () __attribute__((visibility("default")));
+#endif
+
+void fnord () { int i=42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+         if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+       }
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    fi
+    ;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+  # Report which library types will actually be built
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[4-9]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+      if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+  if test "${ac_cv_prog_CXXCPP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+else
+  _lt_caught_CXX_error=yes
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_flag_spec_ld_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+  # save warnings/boilerplate of simple test code
+  ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+  ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  compiler=$CC
+  compiler_CXX=$CC
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test "$GXX" = yes; then
+      lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+    else
+      lt_prog_compiler_no_builtin_flag_CXX=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+       test "$with_gnu_ld" != no && break
+       ;;
+      *)
+       test "$with_gnu_ld" != yes && break
+       ;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test "$with_gnu_ld" = yes; then
+        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='${wl}'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+         $GREP 'no-whole-archive' > /dev/null; then
+          whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          whole_archive_flag_spec_CXX=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+    ld_shlibs_CXX=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+      aix[4-9]*)
+        if test "$host_cpu" = ia64; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=""
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # need to do runtime linking.
+          case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+           for ld_flag in $LDFLAGS; do
+             case $ld_flag in
+             *-brtl*)
+               aix_use_runtimelinking=yes
+               break
+               ;;
+             esac
+           done
+           ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        archive_cmds_CXX=''
+        hardcode_direct_CXX=yes
+        hardcode_direct_absolute_CXX=yes
+        hardcode_libdir_separator_CXX=':'
+        link_all_deplibs_CXX=yes
+        file_list_spec_CXX='${wl}-f,'
+
+        if test "$GXX" = yes; then
+          case $host_os in aix4.[012]|aix4.[012].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+         collect2name=`${CC} -print-prog-name=collect2`
+         if test -f "$collect2name" &&
+            strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+         then
+           # We have reworked collect2
+           :
+         else
+           # We have old collect2
+           hardcode_direct_CXX=unsupported
+           # It fails to find uninstalled libraries when the uninstalled
+           # path is not listed in the libpath.  Setting hardcode_minus_L
+           # to unsupported forces relinking
+           hardcode_minus_L_CXX=yes
+           hardcode_libdir_flag_spec_CXX='-L$libdir'
+           hardcode_libdir_separator_CXX=
+         fi
+          esac
+          shared_flag='-shared'
+         if test "$aix_use_runtimelinking" = yes; then
+           shared_flag="$shared_flag "'${wl}-G'
+         fi
+        else
+          # not using gcc
+          if test "$host_cpu" = ia64; then
+         # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+         # chokes on -Wl,-G. The following line is correct:
+         shared_flag='-G'
+          else
+           if test "$aix_use_runtimelinking" = yes; then
+             shared_flag='${wl}-G'
+           else
+             shared_flag='${wl}-bM:SRE'
+           fi
+          fi
+        fi
+
+        export_dynamic_flag_spec_CXX='${wl}-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+       # export.
+        always_export_symbols_CXX=yes
+        if test "$aix_use_runtimelinking" = yes; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          allow_undefined_flag_CXX='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+       /^0/ {
+           s/^0  *\(.*\)$/\1/
+           p
+       }
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+           hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+           allow_undefined_flag_CXX="-z nodefs"
+           archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+          else
+           # Determine the default libpath from the value encoded in an
+           # empty executable.
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+       /^0/ {
+           s/^0  *\(.*\)$/\1/
+           p
+       }
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+           hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+           # Warning - without using the other run time loading flags,
+           # -berok will link without error, but may produce a broken library.
+           no_undefined_flag_CXX=' ${wl}-bernotok'
+           allow_undefined_flag_CXX=' ${wl}-berok'
+           if test "$with_gnu_ld" = yes; then
+             # We only use this code for GNU lds that support --whole-archive.
+             whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+           else
+             # Exported symbols can be pulled into shared objects from archives
+             whole_archive_flag_spec_CXX='$convenience'
+           fi
+           archive_cmds_need_lc_CXX=yes
+           # This is similar to how AIX traditionally builds its shared
+           # libraries.
+           archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+          fi
+        fi
+        ;;
+
+      beos*)
+       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+         allow_undefined_flag_CXX=unsupported
+         # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+         # support --undefined.  This deserves some investigation.  FIXME
+         archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       else
+         ld_shlibs_CXX=no
+       fi
+       ;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+         # FIXME: insert proper C++ library support
+         ld_shlibs_CXX=no
+         ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+        # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+        # as there is no search path for DLLs.
+        hardcode_libdir_flag_spec_CXX='-L$libdir'
+        export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
+        allow_undefined_flag_CXX=unsupported
+        always_export_symbols_CXX=no
+        enable_shared_with_static_runtimes_CXX=yes
+
+        if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+          archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+          # If the export-symbols file already is a .def file (1st line
+          # is EXPORTS), use it as is; otherwise, prepend...
+          archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+           cp $export_symbols $output_objdir/$soname.def;
+          else
+           echo EXPORTS > $output_objdir/$soname.def;
+           cat $export_symbols >> $output_objdir/$soname.def;
+          fi~
+          $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+        else
+          ld_shlibs_CXX=no
+        fi
+        ;;
+      darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc_CXX=no
+  hardcode_direct_CXX=no
+  hardcode_automatic_CXX=yes
+  hardcode_shlibpath_var_CXX=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  else
+    whole_archive_flag_spec_CXX=''
+  fi
+  link_all_deplibs_CXX=yes
+  allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+       if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
+
+  else
+  ld_shlibs_CXX=no
+  fi
+
+       ;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+           # FIXME: insert proper C++ library support
+           ld_shlibs_CXX=no
+           ;;
+          ghcx*)
+           # Green Hills C++ Compiler
+           # FIXME: insert proper C++ library support
+           ld_shlibs_CXX=no
+           ;;
+          *)
+           # FIXME: insert proper C++ library support
+           ld_shlibs_CXX=no
+           ;;
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+       # switch to ELF
+        ld_shlibs_CXX=no
+        ;;
+
+      freebsd-elf*)
+        archive_cmds_need_lc_CXX=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        ld_shlibs_CXX=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      haiku*)
+        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        link_all_deplibs_CXX=yes
+        ;;
+
+      hpux9*)
+        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        export_dynamic_flag_spec_CXX='${wl}-E'
+        hardcode_direct_CXX=yes
+        hardcode_minus_L_CXX=yes # Not in the search PATH,
+                                            # but as the default
+                                            # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            ld_shlibs_CXX=no
+            ;;
+          aCC*)
+            archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              ld_shlibs_CXX=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+         hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+         hardcode_libdir_separator_CXX=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+             export_dynamic_flag_spec_CXX='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            hardcode_direct_CXX=no
+            hardcode_shlibpath_var_CXX=no
+            ;;
+          *)
+            hardcode_direct_CXX=yes
+            hardcode_direct_absolute_CXX=yes
+            hardcode_minus_L_CXX=yes # Not in the search PATH,
+                                                # but as the default
+                                                # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+           # FIXME: insert proper C++ library support
+           ld_shlibs_CXX=no
+           ;;
+          aCC*)
+           case $host_cpu in
+             hppa*64*)
+               archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+               ;;
+             ia64*)
+               archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+               ;;
+             *)
+               archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+               ;;
+           esac
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           #
+           # There doesn't appear to be a way to prevent this compiler from
+           # explicitly linking system object files so we need to strip them
+           # from the output so that they don't get included in the library
+           # dependencies.
+           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+           ;;
+          *)
+           if test "$GXX" = yes; then
+             if test $with_gnu_ld = no; then
+               case $host_cpu in
+                 hppa*64*)
+                   archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+                   ;;
+                 ia64*)
+                   archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+                   ;;
+                 *)
+                   archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+                   ;;
+               esac
+             fi
+           else
+             # FIXME: insert proper C++ library support
+             ld_shlibs_CXX=no
+           fi
+           ;;
+        esac
+        ;;
+
+      interix[3-9]*)
+       hardcode_direct_CXX=no
+       hardcode_shlibpath_var_CXX=no
+       hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+       export_dynamic_flag_spec_CXX='${wl}-E'
+       # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+       # Instead, shared libraries are loaded at an image base (0x10000000 by
+       # default) and relocated if they conflict, which is a slow very memory
+       # consuming and fragmenting process.  To avoid this, we pick a random,
+       # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+       # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+       archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+       archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+       ;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+           # SGI C++
+           archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+           # Archives containing C++ object files must be created using
+           # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+           # necessary to make sure instantiated templates are included
+           # in the archive.
+           old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+           ;;
+          *)
+           if test "$GXX" = yes; then
+             if test "$with_gnu_ld" = no; then
+               archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+             else
+               archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+             fi
+           fi
+           link_all_deplibs_CXX=yes
+           ;;
+        esac
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        inherit_rpath_CXX=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+        case $cc_basename in
+          KCC*)
+           # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+           # KCC will only create a shared library if the output file
+           # ends with ".so" (or ".sl" for HP-UX), so rename the library
+           # to its proper name (with version) after linking.
+           archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+           archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           #
+           # There doesn't appear to be a way to prevent this compiler from
+           # explicitly linking system object files so we need to strip them
+           # from the output so that they don't get included in the library
+           # dependencies.
+           output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+           hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+           export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+           # Archives containing C++ object files must be created using
+           # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+           old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+           ;;
+         icpc* | ecpc* )
+           # Intel C++
+           with_gnu_ld=yes
+           # version 8.0 and above of icpc choke on multiply defined symbols
+           # if we add $predep_objects and $postdep_objects, however 7.1 and
+           # earlier do not add the objects themselves.
+           case `$CC -V 2>&1` in
+             *"Version 7."*)
+               archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+               archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+               ;;
+             *)  # Version 8.0 or newer
+               tmp_idyn=
+               case $host_cpu in
+                 ia64*) tmp_idyn=' -i_dynamic';;
+               esac
+               archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+               archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+               ;;
+           esac
+           archive_cmds_need_lc_CXX=no
+           hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+           export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+           whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+           ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+           case `$CC -V` in
+           *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
+             prelink_cmds_CXX='tpldir=Template.dir~
+               rm -rf $tpldir~
+               $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+               compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+             old_archive_cmds_CXX='tpldir=Template.dir~
+               rm -rf $tpldir~
+               $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+               $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+               $RANLIB $oldlib'
+             archive_cmds_CXX='tpldir=Template.dir~
+               rm -rf $tpldir~
+               $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+               $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+             archive_expsym_cmds_CXX='tpldir=Template.dir~
+               rm -rf $tpldir~
+               $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+               $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+             ;;
+           *) # Version 6 and above use weak symbols
+             archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+             archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+             ;;
+           esac
+
+           hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+           export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+           whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+         cxx*)
+           # Compaq C++
+           archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+           archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+           runpath_var=LD_RUN_PATH
+           hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+           hardcode_libdir_separator_CXX=:
+
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           #
+           # There doesn't appear to be a way to prevent this compiler from
+           # explicitly linking system object files so we need to strip them
+           # from the output so that they don't get included in the library
+           # dependencies.
+           output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+           ;;
+         xl* | mpixl* | bgxl*)
+           # IBM XL 8.0 on PPC, with GNU ld
+           hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+           export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+           archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+           if test "x$supports_anon_versioning" = xyes; then
+             archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
+               cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+               echo "local: *; };" >> $output_objdir/$libname.ver~
+               $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+           fi
+           ;;
+         *)
+           case `$CC -V 2>&1 | sed 5q` in
+           *Sun\ C*)
+             # Sun C++ 5.9
+             no_undefined_flag_CXX=' -zdefs'
+             archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+             archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+             hardcode_libdir_flag_spec_CXX='-R$libdir'
+             whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+             compiler_needs_object_CXX=yes
+
+             # Not sure whether something based on
+             # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+             # would be better.
+             output_verbose_link_cmd='func_echo_all'
+
+             # Archives containing C++ object files must be created using
+             # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+             # necessary to make sure instantiated templates are included
+             # in the archive.
+             old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+             ;;
+           esac
+           ;;
+       esac
+       ;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+       ;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+           # FIXME: insert proper C++ library support
+           ld_shlibs_CXX=no
+           ;;
+         *)
+           # FIXME: insert proper C++ library support
+           ld_shlibs_CXX=no
+           ;;
+       esac
+       ;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+         archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+         wlarc=
+         hardcode_libdir_flag_spec_CXX='-R$libdir'
+         hardcode_direct_CXX=yes
+         hardcode_shlibpath_var_CXX=no
+       fi
+       # Workaround some broken pre-1.5 toolchains
+       output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+       ;;
+
+      *nto* | *qnx*)
+        ld_shlibs_CXX=yes
+       ;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+       ld_shlibs_CXX=no
+       ;;
+
+      openbsd*)
+       if test -f /usr/libexec/ld.so; then
+         hardcode_direct_CXX=yes
+         hardcode_shlibpath_var_CXX=no
+         hardcode_direct_absolute_CXX=yes
+         archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+         hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+         if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+           archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+           export_dynamic_flag_spec_CXX='${wl}-E'
+           whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+         fi
+         output_verbose_link_cmd=func_echo_all
+       else
+         ld_shlibs_CXX=no
+       fi
+       ;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+           # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+           # KCC will only create a shared library if the output file
+           # ends with ".so" (or ".sl" for HP-UX), so rename the library
+           # to its proper name (with version) after linking.
+           archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+           hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+           hardcode_libdir_separator_CXX=:
+
+           # Archives containing C++ object files must be created using
+           # the KAI C++ compiler.
+           case $host in
+             osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+             *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+           esac
+           ;;
+          RCC*)
+           # Rational C++ 2.4.1
+           # FIXME: insert proper C++ library support
+           ld_shlibs_CXX=no
+           ;;
+          cxx*)
+           case $host in
+             osf3*)
+               allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+               archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+               hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+               ;;
+             *)
+               allow_undefined_flag_CXX=' -expect_unresolved \*'
+               archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+               archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+                 echo "-hidden">> $lib.exp~
+                 $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+                 $RM $lib.exp'
+               hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+               ;;
+           esac
+
+           hardcode_libdir_separator_CXX=:
+
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           #
+           # There doesn't appear to be a way to prevent this compiler from
+           # explicitly linking system object files so we need to strip them
+           # from the output so that they don't get included in the library
+           # dependencies.
+           output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+           ;;
+         *)
+           if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+             allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+             case $host in
+               osf3*)
+                 archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+                 ;;
+               *)
+                 archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+                 ;;
+             esac
+
+             hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+             hardcode_libdir_separator_CXX=:
+
+             # Commands to make compiler produce verbose output that lists
+             # what "hidden" libraries, object files and flags are used when
+             # linking a shared library.
+             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+           else
+             # FIXME: insert proper C++ library support
+             ld_shlibs_CXX=no
+           fi
+           ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+           # Sun C++ 4.x
+           # FIXME: insert proper C++ library support
+           ld_shlibs_CXX=no
+           ;;
+          lcc*)
+           # Lucid
+           # FIXME: insert proper C++ library support
+           ld_shlibs_CXX=no
+           ;;
+          *)
+           # FIXME: insert proper C++ library support
+           ld_shlibs_CXX=no
+           ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC*)
+           # Sun C++ 4.2, 5.x and Centerline C++
+            archive_cmds_need_lc_CXX=yes
+           no_undefined_flag_CXX=' -zdefs'
+           archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+           archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+             $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+           hardcode_libdir_flag_spec_CXX='-R$libdir'
+           hardcode_shlibpath_var_CXX=no
+           case $host_os in
+             solaris2.[0-5] | solaris2.[0-5].*) ;;
+             *)
+               # The compiler driver will combine and reorder linker options,
+               # but understands `-z linker_flag'.
+               # Supported since Solaris 2.6 (maybe 2.5.1?)
+               whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+               ;;
+           esac
+           link_all_deplibs_CXX=yes
+
+           output_verbose_link_cmd='func_echo_all'
+
+           # Archives containing C++ object files must be created using
+           # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+           # necessary to make sure instantiated templates are included
+           # in the archive.
+           old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+           ;;
+          gcx*)
+           # Green Hills C++ Compiler
+           archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+           # The C++ compiler must be used to create the archive.
+           old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+           ;;
+          *)
+           # GNU C++ compiler with Solaris linker
+           if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+             no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+             if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+               archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+               archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+                 $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+               # Commands to make compiler produce verbose output that lists
+               # what "hidden" libraries, object files and flags are used when
+               # linking a shared library.
+               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+             else
+               # g++ 2.7 appears to require `-G' NOT `-shared' on this
+               # platform.
+               archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+               archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+                 $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+               # Commands to make compiler produce verbose output that lists
+               # what "hidden" libraries, object files and flags are used when
+               # linking a shared library.
+               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+             fi
+
+             hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+             case $host_os in
+               solaris2.[0-5] | solaris2.[0-5].*) ;;
+               *)
+                 whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+                 ;;
+             esac
+           fi
+           ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag_CXX='${wl}-z,text'
+      archive_cmds_need_lc_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+         archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+         archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+         archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+       # Note: We can NOT use -z defs as we might desire, because we do not
+       # link with -lc, and that would cause any symbols used from libc to
+       # always be unresolved, which means just about no library would
+       # ever link correctly.  If we're not using GNU ld we use -z text
+       # though, which does catch some bad symbols but isn't as heavy-handed
+       # as -z defs.
+       no_undefined_flag_CXX='${wl}-z,text'
+       allow_undefined_flag_CXX='${wl}-z,nodefs'
+       archive_cmds_need_lc_CXX=no
+       hardcode_shlibpath_var_CXX=no
+       hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
+       hardcode_libdir_separator_CXX=':'
+       link_all_deplibs_CXX=yes
+       export_dynamic_flag_spec_CXX='${wl}-Bexport'
+       runpath_var='LD_RUN_PATH'
+
+       case $cc_basename in
+          CC*)
+           archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+           archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+           old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+             '"$old_archive_cmds_CXX"
+           reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+             '"$reload_cmds_CXX"
+           ;;
+         *)
+           archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+           archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+           ;;
+       esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+           # NonStop-UX NCC 3.20
+           # FIXME: insert proper C++ library support
+           ld_shlibs_CXX=no
+           ;;
+          *)
+           # FIXME: insert proper C++ library support
+           ld_shlibs_CXX=no
+           ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+    esac
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+    test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+    GCC_CXX="$GXX"
+    LD_CXX="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" ||
+          test $p = "-R"; then
+        prev=$p
+        continue
+       else
+        prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+        case $p in
+        -L* | -R*)
+          # Internal compiler library paths should come after those
+          # provided the user.  The postdeps already come after the
+          # user supplied libs so there is no need to process them.
+          if test -z "$compiler_lib_search_path_CXX"; then
+            compiler_lib_search_path_CXX="${prev}${p}"
+          else
+            compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
+          fi
+          ;;
+        # The "-l" case would never come before the object being
+        # linked, so don't bother handling this case.
+        esac
+       else
+        if test -z "$postdeps_CXX"; then
+          postdeps_CXX="${prev}${p}"
+        else
+          postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+        fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+        pre_test_object_deps_done=yes
+        continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+        if test -z "$predep_objects_CXX"; then
+          predep_objects_CXX="$p"
+        else
+          predep_objects_CXX="$predep_objects_CXX $p"
+        fi
+       else
+        if test -z "$postdep_objects_CXX"; then
+          postdep_objects_CXX="$p"
+        else
+          postdep_objects_CXX="$postdep_objects_CXX $p"
+        fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix[3-9]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  predep_objects_CXX=
+  postdep_objects_CXX=
+  postdeps_CXX=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static_CXX='-Bstatic'
+      fi
+      lt_prog_compiler_pic_CXX='-fPIC'
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic_CXX='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static_CXX=
+      ;;
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       lt_prog_compiler_pic_CXX=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+       ;;
+      *)
+       lt_prog_compiler_pic_CXX='-fPIC'
+       ;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic_CXX='-fPIC -shared'
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[4-9]*)
+       # All AIX code is PIC.
+       if test "$host_cpu" = ia64; then
+         # AIX 5 now supports IA64 processor
+         lt_prog_compiler_static_CXX='-Bstatic'
+       else
+         lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+       fi
+       ;;
+      chorus*)
+       case $cc_basename in
+       cxch68*)
+         # Green Hills C++ Compiler
+         # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+         ;;
+       esac
+       ;;
+      dgux*)
+       case $cc_basename in
+         ec++*)
+           lt_prog_compiler_pic_CXX='-KPIC'
+           ;;
+         ghcx*)
+           # Green Hills C++ Compiler
+           lt_prog_compiler_pic_CXX='-pic'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      freebsd* | dragonfly*)
+       # FreeBSD uses GNU C++
+       ;;
+      hpux9* | hpux10* | hpux11*)
+       case $cc_basename in
+         CC*)
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+           if test "$host_cpu" != ia64; then
+             lt_prog_compiler_pic_CXX='+Z'
+           fi
+           ;;
+         aCC*)
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+           case $host_cpu in
+           hppa*64*|ia64*)
+             # +Z the default
+             ;;
+           *)
+             lt_prog_compiler_pic_CXX='+Z'
+             ;;
+           esac
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      interix*)
+       # This is c89, which is MS Visual C++ (no shared libs)
+       # Anyone wants to do a port?
+       ;;
+      irix5* | irix6* | nonstopux*)
+       case $cc_basename in
+         CC*)
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_static_CXX='-non_shared'
+           # CC pic flag -KPIC is the default.
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+       case $cc_basename in
+         KCC*)
+           # KAI C++ Compiler
+           lt_prog_compiler_wl_CXX='--backend -Wl,'
+           lt_prog_compiler_pic_CXX='-fPIC'
+           ;;
+         ecpc* )
+           # old Intel C++ for x86_64 which still supported -KPIC.
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_pic_CXX='-KPIC'
+           lt_prog_compiler_static_CXX='-static'
+           ;;
+         icpc* )
+           # Intel C++, used to be incompatible with GCC.
+           # ICC 10 doesn't accept -KPIC any more.
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_pic_CXX='-fPIC'
+           lt_prog_compiler_static_CXX='-static'
+           ;;
+         pgCC* | pgcpp*)
+           # Portland Group C++ compiler
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_pic_CXX='-fpic'
+           lt_prog_compiler_static_CXX='-Bstatic'
+           ;;
+         cxx*)
+           # Compaq C++
+           # Make sure the PIC flag is empty.  It appears that all Alpha
+           # Linux and Compaq Tru64 Unix objects are PIC.
+           lt_prog_compiler_pic_CXX=
+           lt_prog_compiler_static_CXX='-non_shared'
+           ;;
+         xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+           # IBM XL 8.0, 9.0 on PPC and BlueGene
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_pic_CXX='-qpic'
+           lt_prog_compiler_static_CXX='-qstaticlink'
+           ;;
+         *)
+           case `$CC -V 2>&1 | sed 5q` in
+           *Sun\ C*)
+             # Sun C++ 5.9
+             lt_prog_compiler_pic_CXX='-KPIC'
+             lt_prog_compiler_static_CXX='-Bstatic'
+             lt_prog_compiler_wl_CXX='-Qoption ld '
+             ;;
+           esac
+           ;;
+       esac
+       ;;
+      lynxos*)
+       ;;
+      m88k*)
+       ;;
+      mvs*)
+       case $cc_basename in
+         cxx*)
+           lt_prog_compiler_pic_CXX='-W c,exportall'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      netbsd*)
+       ;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        lt_prog_compiler_pic_CXX='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+       case $cc_basename in
+         KCC*)
+           lt_prog_compiler_wl_CXX='--backend -Wl,'
+           ;;
+         RCC*)
+           # Rational C++ 2.4.1
+           lt_prog_compiler_pic_CXX='-pic'
+           ;;
+         cxx*)
+           # Digital/Compaq C++
+           lt_prog_compiler_wl_CXX='-Wl,'
+           # Make sure the PIC flag is empty.  It appears that all Alpha
+           # Linux and Compaq Tru64 Unix objects are PIC.
+           lt_prog_compiler_pic_CXX=
+           lt_prog_compiler_static_CXX='-non_shared'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      psos*)
+       ;;
+      solaris*)
+       case $cc_basename in
+         CC*)
+           # Sun C++ 4.2, 5.x and Centerline C++
+           lt_prog_compiler_pic_CXX='-KPIC'
+           lt_prog_compiler_static_CXX='-Bstatic'
+           lt_prog_compiler_wl_CXX='-Qoption ld '
+           ;;
+         gcx*)
+           # Green Hills C++ Compiler
+           lt_prog_compiler_pic_CXX='-PIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      sunos4*)
+       case $cc_basename in
+         CC*)
+           # Sun C++ 4.x
+           lt_prog_compiler_pic_CXX='-pic'
+           lt_prog_compiler_static_CXX='-Bstatic'
+           ;;
+         lcc*)
+           # Lucid
+           lt_prog_compiler_pic_CXX='-pic'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+       case $cc_basename in
+         CC*)
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_pic_CXX='-KPIC'
+           lt_prog_compiler_static_CXX='-Bstatic'
+           ;;
+       esac
+       ;;
+      tandem*)
+       case $cc_basename in
+         NCC*)
+           # NonStop-UX NCC 3.20
+           lt_prog_compiler_pic_CXX='-KPIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      vxworks*)
+       ;;
+      *)
+       lt_prog_compiler_can_build_shared_CXX=no
+       ;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_prog_compiler_pic_CXX" >&6; }
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works_CXX=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works_CXX=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works_CXX=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works_CXX=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works_CXX=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
+    :
+else
+    lt_prog_compiler_static_CXX=
+fi
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix[4-9]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+  ;;
+  cygwin* | mingw* | cegcc*)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if test "${lt_cv_archive_cmds_need_lc_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  $RM conftest*
+       echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+       if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+         soname=conftest
+         lib=conftest
+         libobjs=conftest.$ac_objext
+         deplibs=
+         wl=$lt_prog_compiler_wl_CXX
+         pic_flag=$lt_prog_compiler_pic_CXX
+         compiler_flags=-v
+         linker_flags=-v
+         verstring=
+         output_objdir=.
+         libname=conftest
+         lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+         allow_undefined_flag_CXX=
+         if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+         then
+           lt_cv_archive_cmds_need_lc_CXX=no
+         else
+           lt_cv_archive_cmds_need_lc_CXX=yes
+         fi
+         allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+       else
+         cat conftest.err 1>&5
+       fi
+       $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+      archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+          echo ' yes '
+          echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+       :
+      else
+       can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+haiku*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+       if test "$lt_cv_prog_gnu_ld" = yes; then
+               version_type=linux
+       else
+               version_type=irix
+       fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+        LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[      ]*hwcap[        ]/d;s/[:,      ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+    *)                         need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+       shlibpath_overrides_runpath=no
+       ;;
+      *)
+       shlibpath_overrides_runpath=yes
+       ;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+       ;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+   test -n "$runpath_var_CXX" ||
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct_CXX" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink ||
+   test "$inherit_rpath_CXX" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+        ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+
+
+# Must be last
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    test "x$cache_file" != "x/dev/null" &&
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+    cat confcache >$cache_file
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[     `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+       g
+       s/^\n//
+       s/\n/ /g
+       p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  as_fn_error "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${LINUX_LINKER_SCRIPT_TRUE}" && test -z "${LINUX_LINKER_SCRIPT_FALSE}"; then
+  as_fn_error "conditional \"LINUX_LINKER_SCRIPT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MAC_LINKER_SCRIPT_TRUE}" && test -z "${MAC_LINKER_SCRIPT_FALSE}"; then
+  as_fn_error "conditional \"MAC_LINKER_SCRIPT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+       expr "X$arg" : "X\\(.*\\)$as_nl";
+       arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""       $as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='        ';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+       test -d "$1/.";
+      else
+       case $1 in #(
+       -*)set "./$1";;
+       esac;
+       case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+       ???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by Cilk Runtime Library $as_me 2.0, which was
+generated by GNU Autoconf 2.64.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Configuration commands:
+$config_commands
+
+Report bugs to <cilk@intel.com>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+Cilk Runtime Library config.status 2.0
+configured by $0, generated by GNU Autoconf 2.64,
+  with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h |  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+srcdir="$srcdir"
+host="$host"
+target="$target"
+with_multisubdir="$with_multisubdir"
+with_multisrctop="$with_multisrctop"
+with_target_subdir="$with_target_subdir"
+ac_configure_args="${multilib_arg} ${ac_configure_args}"
+multi_basedir="$multi_basedir"
+CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+CC="$CC"
+CXX="$CXX"
+GFORTRAN="$GFORTRAN"
+GCJ="$GCJ"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+fix_srcfile_path_CXX='`$ECHO "$fix_srcfile_path_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+AR \
+AR_FLAGS \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_wl \
+lt_prog_compiler_pic \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_flag_spec_ld \
+hardcode_libdir_separator \
+fix_srcfile_path \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+reload_flag_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_flag_spec_ld_CXX \
+hardcode_libdir_separator_CXX \
+fix_srcfile_path_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+reload_cmds_CXX \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'
+
+
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+
+  *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = "\a"
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+  || as_fn_error "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[    ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[      ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X "  :F $CONFIG_FILES      :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+        # (if the path is not absolute).  The absolute path cannot be DOS-style,
+        # because $ac_f cannot contain `:'.
+        test -f "$ac_f" ||
+          case $ac_f in
+          [\\/$]*) false;;
+          *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+          esac ||
+          as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+         $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+       `' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin" \
+      || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&2;}
+
+  rm -f "$tmp/stdin"
+  case $ac_file in
+  -) cat "$tmp/out" && rm -f "$tmp/out";;
+  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
+ ;;
+
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named `Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$mf" : 'X\(//\)[^/]' \| \
+        X"$mf" : 'X\(//\)$' \| \
+        X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running `make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # When using ansi2knr, U may be empty or an underscore; expand it
+    U=`sed -n 's/^U = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$file" : 'X\(//\)[^/]' \| \
+        X"$file" : 'X\(//\)$' \| \
+        X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+      as_dir=$dirpart/$fdir; as_fn_mkdir_p
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+ ;;
+    "default-1":C)
+# Only add multilib support code if we just rebuilt the top-level
+# Makefile.
+case " $CONFIG_FILES " in
+ *" Makefile "*)
+   ac_file=Makefile . ${multi_basedir}/config-ml.in
+   ;;
+esac ;;
+    "libtool":C)
+
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking.  This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  case $xsi_shell in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+  func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+  # positional parameters, so assign one to ordinary parameter first.
+  func_stripname_result=${3}
+  func_stripname_result=${func_stripname_result#"${1}"}
+  func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=${1%%=*}
+  func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  case ${1} in
+    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+    *)    func_lo2o_result=${1} ;;
+  esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=$(( $* ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=${#1}
+}
+
+_LT_EOF
+    ;;
+  *) # Bourne compatible functions.
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  # Extract subdirectory from the argument.
+  func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+  if test "X$func_dirname_result" = "X${1}"; then
+    func_dirname_result="${3}"
+  else
+    func_dirname_result="$func_dirname_result${2}"
+  fi
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+}
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+  case ${2} in
+    .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+    *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[^=]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"`
+  func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=`expr "$@"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$1+=\$2"
+}
+_LT_EOF
+    ;;
+  *)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$1=\$$1\$2"
+}
+
+_LT_EOF
+    ;;
+  esac
+
+
+  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+
+    cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking.  This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit $?
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/libcilkrts/configure.ac b/libcilkrts/configure.ac
new file mode 100644 (file)
index 0000000..9acdc11
--- /dev/null
@@ -0,0 +1,148 @@
+#  @copyright
+#  Copyright (C) 2011-2013, Intel Corporation
+#  All rights reserved.
+#  
+#  @copyright
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions
+#  are met:
+#  
+#    * Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#    * Neither the name of Intel Corporation nor the names of its
+#      contributors may be used to endorse or promote products derived
+#      from this software without specific prior written permission.
+#  
+#  @copyright
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+#  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+#  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+#  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+#  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+
+AC_INIT([Cilk Runtime Library], [2.0], [cilk@intel.com])
+AC_PREREQ([2.64])
+
+# Needed to define ${target}.  Needs to be very early to avoid annoying
+# warning about calling AC_ARG_PROGRAM before AC_CANONICAL_SYSTEM
+AC_CANONICAL_SYSTEM
+AM_INIT_AUTOMAKE(foreign no-dist)
+
+# Build a DLL on Windows
+# AC_LIBTOOL_WIN32_DLL
+AC_PROG_CXX
+AC_PROG_CC
+# AC_PROG_LIBTOOL
+# AC_CONFIG_MACRO_DIR([..])
+AC_CONFIG_FILES([Makefile])
+AM_ENABLE_MULTILIB(, ..)
+
+# Get target configury.
+. ${srcdir}/configure.tgt
+if test -n "$UNSUPPORTED"; then
+   AC_MSG_ERROR([Configuration ${target} is unsupported.])
+fi
+
+if test "${multilib}" = "yes"; then
+  multilib_arg="--enable-multilib"
+else
+  multilib_arg=
+fi
+
+AC_MSG_CHECKING([for --enable-version-specific-runtime-libs])
+AC_ARG_ENABLE([version-specific-runtime-libs],
+  AC_HELP_STRING([--enable-version-specific-runtime-libs],
+                 [Specify that runtime libraries should be installed in a compi
+ler-specific directory]),
+  [case "$enableval" in
+    yes) enable_version_specific_runtime_libs=yes ;;
+    no)  enable_version_specific_runtime_libs=no ;;
+    *)   AC_MSG_ERROR([Unknown argument to enable/disable version-specific libs
+]);;
+   esac],
+  [enable_version_specific_runtime_libs=no])
+AC_MSG_RESULT($enable_version_specific_runtime_libs)
+
+
+# Calculate toolexeclibdir
+# Also toolexecdir, though it's only used in toolexeclibdir
+case ${enable_version_specific_runtime_libs} in
+  yes)
+    # Need the gcc compiler version to know where to install libraries
+    # and header files if --enable-version-specific-runtime-libs option
+    # is selected.
+    toolexecdir='$(libdir)/gcc/$(target_alias)'
+   toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
+    ;;
+  no)
+    if test -n "$with_cross_host" &&
+       test x"$with_cross_host" != x"no"; then
+      # Install a library built with a cross compiler in tooldir, not libdir.
+      toolexecdir='$(exec_prefix)/$(target_alias)'
+      toolexeclibdir='$(toolexecdir)/lib'
+    else
+      toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
+      toolexeclibdir='$(libdir)'
+    fi
+    multi_os_directory=`$CC -print-multi-os-directory`
+    case $multi_os_directory in
+      .) ;; # Avoid trailing /.
+      *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+    esac
+    ;;
+esac
+
+# Set config_dir based on the target.  config_dir specifies where to get
+# target-specific files.  The generic implementation is incomplete, but
+# contains information on what's needed
+case "${target}" in
+
+  x86_64-*-*)
+    config_dir="x86"
+    ;;
+
+  i[456]86-*-*)
+    config_dir="x86"
+    ;;
+
+  *)
+    config_dir="generic"
+    ;;
+
+esac
+AC_SUBST(config_dir)
+
+# We have linker scripts for appropriate operating systems
+linux_linker_script=no
+case "${host}" in
+    *-*-linux*)
+        linux_linker_script=yes
+        ;;
+esac
+AM_CONDITIONAL(LINUX_LINKER_SCRIPT, test "$linux_linker_script" = "yes")
+
+mac_linker_script=no
+case "${host}" in
+    *-*-apple*)
+        mac_linker_script=yes
+        ;;
+esac
+AM_CONDITIONAL(MAC_LINKER_SCRIPT, test "$mac_linker_script" = "yes")
+
+AM_PROG_LIBTOOL
+AC_SUBST(toolexecdir)
+AC_SUBST(toolexeclibdir)
+
+# Must be last
+AC_OUTPUT
diff --git a/libcilkrts/configure.tgt b/libcilkrts/configure.tgt
new file mode 100644 (file)
index 0000000..f766352
--- /dev/null
@@ -0,0 +1,61 @@
+#  @copyright
+#  Copyright (C) 2011-2013, Intel Corporation
+#  All rights reserved.
+#  
+#  @copyright
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions
+#  are met:
+#  
+#    * Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#    * Neither the name of Intel Corporation nor the names of its
+#      contributors may be used to endorse or promote products derived
+#      from this software without specific prior written permission.
+#  
+#  @copyright
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+#  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+#  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+#  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+#  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+
+# Disable Cilk Runtime library for non x86 architecture...for now.
+case "${target}" in
+  x86_64-*-*)
+    ;;
+  i?86-*-*)
+    ;;
+  *-*-*)
+    UNSUPPORTED=1
+    ;;
+esac
+
+# Disable libcilkrts on non POSIX hosted systems.
+if test x$enable_libcilkrts = x ; then
+    # Enable libcilkrts by default on hosted POSIX systems.
+    case "${target}" in
+    *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
+        ;;
+    *-*-netbsd* | *-*-freebsd* | *-*-openbsd* | *-*-dragonfly*)
+        ;;
+    *-*-solaris2* | *-*-hpux11*)
+        ;;
+    *-*-darwin* | *-*-aix*)
+        ;;
+    *)
+        UNSUPPORTED=1
+        ;;
+    esac
+fi
diff --git a/libcilkrts/include/cilk/cilk.h b/libcilkrts/include/cilk/cilk.h
new file mode 100644 (file)
index 0000000..2d0de0d
--- /dev/null
@@ -0,0 +1,71 @@
+/*  cilk.h                  -*-C++-*-
+ *
+ *  @copyright
+ *  Copyright (C) 2010-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+/** @file cilk.h
+ *
+ *  @brief Provides convenient aliases for the Cilk language keywords.
+ *
+ *  @details
+ *  Since Cilk is a nonstandard extension to both C and C++, the Cilk
+ *  language keywords all begin with “`_Cilk_`”, which guarantees that they
+ *  will not conflict with user-defined identifiers in properly written 
+ *  programs, so that “standard” C and C++ programs can safely be
+ *  compiled a Cilk-enabled C or C++ compiler.
+ *
+ *  However, this means that the keywords _look_ like something grafted on to
+ *  the base language. Therefore, you can include this header:
+ *
+ *      #include "cilk/cilk.h"
+ *
+ *  and then write the Cilk keywords with a “`cilk_`” prefix instead of
+ *  “`_Cilk_`”.
+ *
+ *  @ingroup language
+ */
+/** @defgroup language Language Keywords
+ *  Definitions having to do with the Cilk language.
+ *  @{
+ */
+#ifndef cilk_spawn
+# define cilk_spawn _Cilk_spawn ///< Spawn a task that can execute in parallel.
+# define cilk_sync  _Cilk_sync  ///< Wait for spawned tasks to complete.
+# define cilk_for   _Cilk_for   ///< Execute iterations of a for loop in parallel.
+#endif
+
+/// @}
diff --git a/libcilkrts/include/cilk/cilk_api.h b/libcilkrts/include/cilk/cilk_api.h
new file mode 100644 (file)
index 0000000..a21687b
--- /dev/null
@@ -0,0 +1,424 @@
+/*  cilk_api.h
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+/** @file cilk_api.h
+ *
+ * @brief Defines the documented API exposed by the Cilk Plus for use
+ * by applications.
+ *
+ *  @ingroup api
+ */
+#ifndef INCLUDED_CILK_API_H
+#define INCLUDED_CILK_API_H
+
+/** @defgroup api Runtime API
+ *  API to allow user programs to interact with the Cilk runtime.
+ *  @{
+ */
+
+#ifndef CILK_STUB /* Real (non-stub) definitions */
+
+#if ! defined(__cilk) && ! defined(USE_CILK_API)
+#   ifdef _WIN32
+#       error Cilk API is being used with non-Cilk compiler (or Cilk is disabled)
+#   else
+#       warning Cilk API is being used with non-Cilk compiler (or Cilk is disabled)
+#   endif
+#endif
+
+#include <cilk/common.h>
+
+#ifdef __cplusplus
+#   include <cstddef>  /* Defines size_t */
+#else
+#   include <stddef.h> /* Defines size_t */
+#endif
+
+#ifdef _WIN32
+#   ifndef IN_CILK_RUNTIME
+/* Ensure the library is brought if any of these functions are being called. */
+#       pragma comment(lib, "cilkrts")
+#   endif
+
+#   ifndef __cplusplus
+#       include <wchar.h>
+#   endif
+#endif /* _WIN32 */
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/** Return values from __cilkrts_set_param() and __cilkrts_set_param_w() 
+ */
+enum __cilkrts_set_param_status {
+    __CILKRTS_SET_PARAM_SUCCESS = 0, /**< Success - parameter set */
+    __CILKRTS_SET_PARAM_UNIMP   = 1, /**< Unimplemented parameter */
+    __CILKRTS_SET_PARAM_XRANGE  = 2, /**< Parameter value out of range */
+    __CILKRTS_SET_PARAM_INVALID = 3, /**< Invalid parameter value */
+    __CILKRTS_SET_PARAM_LATE    = 4  /**< Too late to change parameter value */
+};
+
+/** Set user controllable runtime parameters
+ *
+ *  Call this function to set runtime parameters that control the behavior 
+ *  of the Cilk scheduler.
+ *
+ *  @param param    A string specifying the parameter to be set. One of:
+ *  -   `"nworkers"`
+ *  -   `"force reduce"`
+ *  @param value    A string specifying the parameter value.
+ *  @returns        A value from the @ref __cilkrts_set_param_status 
+ *                  enumeration indicating the result of the operation.
+ *
+ *  @par The "nworkers" parameter
+ *
+ *  This parameter specifies the number of worker threads to be created by the
+ *  Cilk runtime. @a Value must be a string of digits to be parsed by 
+ *  `strtol()`.
+ *
+ *  The number of worker threads is:
+ *  1.  the value set with `__cilkrts_set_param("nworkers")`, if it is 
+ *      positive; otherwise,
+ *  2.  the value of the CILK_NWORKERS environment variable, if it is 
+ *      defined; otherwise
+ *  3.  the number of cores available, as reported by the operating system.
+ *
+ *  @note
+ *  Technically, Cilk distinguishes between the _user thread_ (the thread that
+ *  the user code was executing on when the Cilk runtime started), and 
+ *  _worker threads_ (new threads created by the Cilk runtime to support
+ *  Cilk parallelism). `nworkers` actually includes both the user thread and
+ *  the worker threads; that is, it is one greater than the number of true
+ *  “worker threads”.
+ *
+ *  @note
+ *  Setting `nworkers = 1` produces serial behavior. Cilk spawns and syncs will
+ *  be executed, but with only one worker, continuations will never be stolen,
+ *  so all code will execute in serial.
+ *
+ *  @warning
+ *  The number of worker threads can only be set *before* the runtime has 
+ *  started. Attempting to set it when the runtime is running will have no 
+ *  effect, and will return an error code. You can call __cilkrts_end_cilk() 
+ *  to shut down the runtime to change the number of workers.
+ *
+ *  @warning
+ *  The default Cilk scheduler behavior is usually pretty good. The ability
+ *  to override `nworkers` can be useful for experimentation, but it won’t
+ *  usually be necessary for getting good performance.
+ *
+ *  @par The "force reduce" parameter
+ *
+ *  This parameter controls whether the runtime should allocate a new view
+ *  for a reducer for every parallel strand that it is accessed on. (See 
+ *  @ref pagereducers.) @a Value must be `"1"` or `"true"` to enable the 
+ *  “force reduce” behavior, or `"0"` or `"false"` to disable it.
+ *
+ *  “Force reduce” behavior will also be enabled if 
+ *  `__cilkrts_set_param("force reduce")` is not called, but the
+ *  `CILK_FORCE_REDUCE` environment variable is defined.
+ *
+ *  @warning
+ *  When this option is enabled, `nworkers` should be set to `1`. Using “force
+ *  reduce” with more than one worker may result in runtime errors.
+ *  
+ *  @warning
+ *  Enabling this option can significantly reduce performance. It should
+ *  _only_ be used as a debugging tool.
+ */
+CILK_API(int) __cilkrts_set_param(const char *param, const char *value);
+
+#ifdef _WIN32
+/**
+ * Set user controllable parameters using wide strings
+ *
+ * @note This variant of __cilkrts_set_param() is only available
+ * on Windows.
+ *
+ * @copydetails __cilkrts_set_param
+ */
+CILK_API(int) __cilkrts_set_param_w(const wchar_t *param, const wchar_t *value);
+#endif
+
+/** Shut down and deallocate all Cilk state.  The runtime will abort the
+ *  application if Cilk is still in use by this thread.  Otherwise the runtime
+ *  will wait for all other threads using Cilk to exit.
+ */
+CILK_API(void) __cilkrts_end_cilk(void);
+
+/** Initialize the Cilk data structures and start the runtime.
+ */
+CILK_API(void) __cilkrts_init(void);
+
+/** Return the runtime `nworkers` parameter. (See the discussion of `nworkers`
+ *  in the documentation for __cilkrts_set_param().)
+ */
+CILK_API(int) __cilkrts_get_nworkers(void);
+
+/** Return the number of thread data structures.
+ *
+ *  This function returns the number of data structures that has been allocated 
+ *  allocated by the runtime to hold information about user and worker threads.
+ *
+ *  If you don’t already know what this is good for, then you probably don’t
+ *  need it.
+ */
+CILK_API(int) __cilkrts_get_total_workers(void);
+
+/** What thread is the function running on?
+ *
+ *  Return a small integer identifying the current thread. Each worker thread
+ *  started by the Cilk runtime library has a unique worker number in the range 
+ *  `1 .. nworkers - 1`.
+ *
+ *  All _user_ threads (threads started by the user, or by other libraries) are
+ *  identified as worker number 0. Therefore, the worker number is not unique
+ *  across multiple user threads.
+ */
+CILK_API(int) __cilkrts_get_worker_number(void);
+
+/** Test whether “force reduce” behavior is enabled.
+ *  
+ *  @return Non-zero if force-reduce mode is on, zero if it is off.
+ */
+CILK_API(int) __cilkrts_get_force_reduce(void);
+
+/** Interact with tools
+ */
+CILK_API(void)
+    __cilkrts_metacall(unsigned int tool, unsigned int code, void *data);
+
+#ifdef _WIN32
+/// Windows exception description record.
+typedef struct _EXCEPTION_RECORD _EXCEPTION_RECORD;
+
+/** Function signature for Windows exception notification callbacks.
+ */
+typedef void (*__cilkrts_pfn_seh_callback)(const _EXCEPTION_RECORD *exception);
+
+/** Specify a function to call when a non-C++ exception is caught.
+ *
+ *  Cilk Plus parallelism plays nicely with C++ exception handling, but the 
+ *  Cilk Plus runtime has no way to unwind the stack across a strand boundary 
+ *  for Microsoft SEH (“Structured Exception Handling”) exceptions. Therefore, 
+ *  when the runtime catches such an exception, it must abort the application.
+ *
+ *  If an SEH callback has been set, the runtime will call it before aborting.
+ *
+ *  @param  pfn A pointer to a callback function to be called before the
+ *              runtime aborts the program because of an SEH exception.
+ */
+CILK_API(int) __cilkrts_set_seh_callback(__cilkrts_pfn_seh_callback pfn);
+#endif /* _WIN32 */
+
+#if __CILKRTS_ABI_VERSION >= 1
+/* Pedigree API is available only for compilers that use ABI version >= 1. */
+
+
+/** @name Pedigrees
+ */
+//@{
+
+// @cond internal
+
+/** Support for __cilkrts_get_pedigree.
+ */
+CILK_API(__cilkrts_pedigree)
+__cilkrts_get_pedigree_internal(__cilkrts_worker *w);
+
+/** Support for __cilkrts_bump_worker_rank.
+ */
+CILK_API(int)
+__cilkrts_bump_worker_rank_internal(__cilkrts_worker* w);
+
+/// @endcond
+
+
+/** Get the current pedigree, in a linked list representation.
+ *
+ *  This routine returns a copy of the last node in the pedigree list.
+ *  For example, if the current pedigree (in order) is <1, 2, 3, 4>,
+ *  then this method returns a node with rank == 4, and whose parent
+ *  field points to the node with rank of 3.  In summary, following the
+ *  nodes in the chain visits the terms of the pedigree in reverse.
+ * 
+ *  The returned node is guaranteed to be valid only until the caller
+ *  of this routine has returned.
+ */
+__CILKRTS_INLINE
+__cilkrts_pedigree __cilkrts_get_pedigree(void) 
+{
+    return __cilkrts_get_pedigree_internal(__cilkrts_get_tls_worker());    
+}
+
+/** Context used by __cilkrts_get_pedigree_info.
+ *
+ *  @deprecated
+ *  This data structure is only used by the deprecated 
+ *  __cilkrts_get_pedigree_info function.
+ *
+ *  Callers should initialize the `data` array to NULL and set the `size`
+ *  field to `sizeof(__cilkrts_pedigree_context_t)` before the first call
+ *  to __cilkrts_get_pedigree_info(), and should not examine or modify it
+ *  thereafter.
+ */
+typedef struct
+{
+    __STDNS size_t size;    /**< Size of the struct in bytes */
+    void *data[3];          /**< Opaque context data */
+} __cilkrts_pedigree_context_t;
+
+/** Get pedigree information.
+ *
+ *  @deprecated
+ *  Use __cilkrts_get_pedigree() instead.
+ *
+ *  This routine allows code to walk up the stack of Cilk frames to gather
+ *  the pedigree.
+ *
+ *  Initialize the pedigree walk by filling the pedigree context with NULLs
+ *  and setting the size field to sizeof(__cilkrts_pedigree_context).
+ *  Other than initialization to NULL to start the walk, user coder should
+ *  consider the pedigree context data opaque and should not examine or
+ *  modify it.
+ *
+ * @returns  0 - Success - birthrank is valid
+ * @returns >0 - End of pedigree walk
+ * @returns -1 - Failure - No worker bound to thread
+ * @returns -2 - Failure - Sanity check failed,
+ * @returns -3 - Failure - Invalid context size
+ * @returns -4 - Failure - Internal error - walked off end of chain of frames
+ */
+CILK_API(int)
+__cilkrts_get_pedigree_info(/* In/Out */ __cilkrts_pedigree_context_t *context,
+                            /* Out */    uint64_t *sf_birthrank);
+
+/** Get the rank of the currently executing worker.
+ *
+ *  @deprecated
+ *  Use `__cilkrts_get_pedigree().rank` instead.
+ *
+ * @returns  0 - Success - *rank is valid
+ * @returns <0 - Failure - *rank is not changed
+ */
+CILK_EXPORT_AND_INLINE
+int __cilkrts_get_worker_rank(uint64_t *rank) 
+{
+    *rank = __cilkrts_get_pedigree().rank;
+    return 0;
+}
+
+/** Increment the pedigree rank of the currently executing worker.
+ *
+ * @returns 0 - Success - rank was incremented
+ * @returns-1 - Failure
+ */
+CILK_EXPORT_AND_INLINE
+int __cilkrts_bump_worker_rank(void)
+{
+    return __cilkrts_bump_worker_rank_internal(__cilkrts_get_tls_worker());
+}
+
+/** Increment the pedigree rank for a cilk_for loop. 
+ *  Obsolete.
+ *
+ *  @deprecated
+ *  This function was provided to allow the user to manipulate the pedigree
+ *  rank of a `cilk_for` loop. The compiler now generates code to do that
+ *  manipulation automatically, so this function is now unnecessary. It may
+ *  be called, but will have no effect.
+ */
+CILK_EXPORT_AND_INLINE
+int __cilkrts_bump_loop_rank(void) 
+{
+    return 0;
+}
+
+//@}
+
+#endif /* __CILKRTS_ABI_VERSION >= 1 */
+
+__CILKRTS_END_EXTERN_C
+
+#else /* CILK_STUB */
+
+// Programs compiled with CILK_STUB are not linked with the Cilk runtime 
+// library, so they should not have external references to runtime functions.
+// Therefore, the functions are replaced with stubs.
+
+#ifdef _WIN32
+#define __cilkrts_set_param_w(name,value) ((value), 0)
+#define __cilkrts_set_seh_callback(pfn) (0)
+#endif
+#define __cilkrts_set_param(name,value) ((value), 0)
+#define __cilkrts_end_cilk() ((void) 0)
+#define __cilkrts_init() ((void) 0)
+#define __cilkrts_get_nworkers() (1)
+#define __cilkrts_get_total_workers() (1)
+#define __cilkrts_get_worker_number() (0)
+#define __cilkrts_get_force_reduce() (0)
+#define __cilkrts_metacall(tool,code,data) ((tool), (code), (data), 0)
+
+#if __CILKRTS_ABI_VERSION >= 1
+/* Pedigree stubs */
+#define __cilkrts_get_pedigree_info(context, sf_birthrank) (-1)
+#define __cilkrts_get_worker_rank(rank) (*(rank) = 0)
+#define __cilkrts_bump_worker_rank() (-1)
+#define __cilkrts_bump_loop_rank() (-1)
+
+/*
+ * A stub method for __cilkrts_get_pedigree.
+ * Returns an empty __cilkrts_pedigree. 
+ */ 
+__CILKRTS_INLINE
+__cilkrts_pedigree __cilkrts_get_pedigree_stub(void)
+{
+    __cilkrts_pedigree ans;
+    ans.rank = 0;
+    ans.parent = NULL;
+    return ans;
+}
+
+/* Renamed to an actual stub method. */
+#define __cilkrts_get_pedigree() __cilkrts_get_pedigree_stub()
+
+#endif /* __CILKRTS_ABI_VERSION >= 1 */
+
+#endif /* CILK_STUB */
+
+//@}
+
+#endif /* INCLUDED_CILK_API_H */
diff --git a/libcilkrts/include/cilk/cilk_api_linux.h b/libcilkrts/include/cilk/cilk_api_linux.h
new file mode 100644 (file)
index 0000000..ed9e706
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* THIS FILE IS DEPRECATED.  USE cilk_api.h INSTEAD. */
+#include <cilk/cilk_api.h>
diff --git a/libcilkrts/include/cilk/cilk_stub.h b/libcilkrts/include/cilk/cilk_stub.h
new file mode 100644 (file)
index 0000000..116e3ff
--- /dev/null
@@ -0,0 +1,55 @@
+/*  cilk_stub.h                  -*-C++-*-
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_CILK_STUB_DOT_H
+#define INCLUDED_CILK_STUB_DOT_H
+
+/* Definitions for creating a serialization from a Cilk program.
+ * These definitions are suitable for use by a compiler that is not
+ * Cilk-enabled.
+ */
+
+/* Pretend we are a non-Cilk compiler */
+#undef __cilk
+#define CILK_STUB
+
+/* Replace Cilk keywords with serial equivalents */
+#define _Cilk_spawn
+#define _Cilk_sync
+#define _Cilk_for for
+
+#endif /* ! defined(INCLUDED_CILK_STUB_DOT_H) */
diff --git a/libcilkrts/include/cilk/cilk_undocumented.h b/libcilkrts/include/cilk/cilk_undocumented.h
new file mode 100644 (file)
index 0000000..81cdd64
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ *
+ * cilk_undocumented.h
+ *
+ * This file defines exported functions that are not included in the standard
+ * documentation.
+ */
+
+#ifndef INCLUDED_CILK_UNDOCUMENTED_H
+#define INCLUDED_CILK_UNDOCUMENTED_H
+
+#include <cilk/common.h>
+
+#ifndef CILK_STUB
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/*
+ * __cilkrts_synched
+ *
+ * Allows an application to determine if there are any outstanding children at
+ * this instant. This function will examine the current full frame to
+ * determine this. This function will return a valid result only when called
+ * within a spawn continuation, within the stack frame of the continuation
+ * itself.
+ */
+
+CILK_EXPORT __CILKRTS_NOTHROW
+int __cilkrts_synched(void);
+
+/*
+ * __cilkrts_cilkscreen_puts
+ *
+ * Allows an application to write a string to the Cilkscreen log.
+ * The standard error stream will be flushed after the write.
+ */
+
+CILK_EXPORT __CILKRTS_NOTHROW
+void __cilkrts_cilkscreen_puts(const char *);
+
+/*
+ * __cilkrts_get_sf
+ *
+ * A debugging aid that allows an application to get the __cilkrts_stack_frame
+ * for the current function.  Only compiled into the DLL in debug builds.
+ */
+
+CILK_EXPORT __CILKRTS_NOTHROW
+void *__cilkrts_get_sf(void);
+
+/**
+ * Returns the size of stacks created by Cilk.
+ */
+CILK_EXPORT __CILKRTS_NOTHROW
+size_t __cilkrts_get_stack_size(void);
+
+/** 
+ * Dumps runtime statistics to stderr.
+ * Undocumented API for debugging. 
+ */
+CILK_EXPORT __CILKRTS_NOTHROW
+void __cilkrts_dump_stats(void);
+
+CILK_EXPORT __CILKRTS_NOTHROW
+int __cilkrts_irml_version(void);
+
+struct __cilk_tbb_unwatch_thunk;
+struct __cilk_tbb_stack_op_thunk;
+
+CILK_EXPORT __CILKRTS_NOTHROW
+int __cilkrts_watch_stack(struct __cilk_tbb_unwatch_thunk *u,
+                          struct __cilk_tbb_stack_op_thunk o);
+
+#ifndef IN_CILK_RUNTIME
+#ifdef _WIN32
+/* Do not use CILK_API because __cilkrts_worker_stub must be __stdcall */
+CILK_EXPORT unsigned __CILKRTS_NOTHROW __stdcall
+__cilkrts_worker_stub(void *arg);
+#else
+/* Do not use CILK_API because __cilkrts_worker_stub have default visibility */
+CILK_EXPORT void* __CILKRTS_NOTHROW
+__cilkrts_worker_stub(void *arg);
+#endif /* _WIN32 */
+#endif /* IN_CILK_RUNTIME */
+
+__CILKRTS_END_EXTERN_C
+
+#else /* CILK_STUB */
+
+/* Stubs for the api functions */
+
+#define __cilkrts_get_stack_size() (0)
+#define __cilkrts_synched() (1)
+
+#endif /* CILK_STUB */
+
+#endif /* INCLUDED_CILK_UNDOCUMENTED_H */
diff --git a/libcilkrts/include/cilk/common.h b/libcilkrts/include/cilk/common.h
new file mode 100644 (file)
index 0000000..8ec19af
--- /dev/null
@@ -0,0 +1,376 @@
+/** common.h
+ *
+ *  @copyright
+ *  Copyright (C) 2010-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+/** @file common.h
+ *
+ * @brief Defines common macros and structures used by the Intel Cilk Plus
+ * runtime.
+ *
+ *  @ingroup common
+ */
+
+/** @defgroup common Common Definitions
+ *  Macro, structure, and class definitions used elsewhere in the runtime.
+ *  @{
+ */
+#ifndef INCLUDED_CILK_COMMON
+#define INCLUDED_CILK_COMMON
+
+#ifdef __cplusplus
+/** Namespace for all Cilk definitions that can be included in user code.
+ */
+namespace cilk {
+    
+    /** Namespace for definitions that are primarily intended for use
+     *  in other Cilk definitions.
+     */
+    namespace internal {}
+}
+#endif
+
+/** Cilk library version = 1.01
+ */
+#define CILK_LIBRARY_VERSION 102
+
+#ifdef __cplusplus
+#   include <cassert>
+#else
+#   include <assert.h>
+#endif
+
+/**
+ * Prefix standard library function and type names with __STDNS in order to
+ * get correct lookup in both C and C++.
+ */
+#ifdef __cplusplus
+#   define __STDNS std::
+#else
+#   define __STDNS
+#endif
+
+/**
+ * @def CILK_EXPORT
+ * Define export of runtime functions from shared library.
+ * Should be exported only from cilkrts*.dll/cilkrts*.so
+ * @def CILK_EXPORT_DATA
+ * Define export of runtime data from shared library.
+ */
+#ifdef _WIN32
+#   ifdef IN_CILK_RUNTIME
+#       define CILK_EXPORT      __declspec(dllexport)
+#       define CILK_EXPORT_DATA __declspec(dllexport)
+#   else
+#       define CILK_EXPORT      __declspec(dllimport)
+#       define CILK_EXPORT_DATA __declspec(dllimport)
+#   endif  /* IN_CILK_RUNTIME */
+#elif defined(__CYGWIN__) || defined(__APPLE__) || defined(_DARWIN_C_SOURCE)
+#   define CILK_EXPORT      /* nothing */
+#   define CILK_EXPORT_DATA /* nothing */
+#else /* Unix/gcc */
+#   ifdef IN_CILK_RUNTIME
+#       define CILK_EXPORT      __attribute__((visibility("protected")))
+#       define CILK_EXPORT_DATA __attribute__((visibility("protected")))
+#   else
+#       define CILK_EXPORT      /* nothing */
+#       define CILK_EXPORT_DATA /* nothing */
+#   endif  /* IN_CILK_RUNTIME */
+#endif /* Unix/gcc */
+
+/**
+ * @def __CILKRTS_BEGIN_EXTERN_C
+ * Macro to denote the start of a section in which all names have "C" linkage.
+ * That is, none of the names are to be mangled.
+ * @see __CILKRTS_END_EXTERN_C
+ * @see __CILKRTS_EXTERN_C
+ *
+ * @def __CILKRTS_END_EXTERN_C
+ * Macro to denote the end of a section in which all names have "C" linkage.
+ * That is, none of the names are to be mangled.
+ * @see __CILKRTS_BEGIN_EXTERN_C
+ * @see __CILKRTS_EXTERN_C
+ *
+ * @def __CILKRTS_EXTERN_C
+ * Macro to prefix a single definition which has "C" linkage.
+ * That is, the defined name is not to be mangled.
+ * @see __CILKRTS_BEGIN_EXTERN_C
+ * @see __CILKRTS_END_EXTERN_C
+ */
+#ifdef __cplusplus
+#   define __CILKRTS_BEGIN_EXTERN_C     extern "C" {
+#   define __CILKRTS_END_EXTERN_C       }
+#   define __CILKRTS_EXTERN_C           extern "C"
+#else
+#   define __CILKRTS_BEGIN_EXTERN_C
+#   define __CILKRTS_END_EXTERN_C
+#   define __CILKRTS_EXTERN_C
+#endif
+
+/**
+ * OS-independent macro to specify a function which is known to not throw
+ * an exception.
+ */ 
+#ifdef __cplusplus
+#   ifdef _WIN32
+#       define __CILKRTS_NOTHROW __declspec(nothrow)
+#   else /* Unix/gcc */
+#       define __CILKRTS_NOTHROW __attribute__((nothrow))
+#   endif /* Unix/gcc */
+#else
+#   define __CILKRTS_NOTHROW /* nothing */
+#endif /* __cplusplus */
+
+/** Cache alignment. (Good enough for most architectures.)
+ */
+#define __CILKRTS_CACHE_LINE__ 64
+
+/**
+ * Macro to specify alignment of a data member in a structure.
+ * Because of the way that gcc’s alignment attribute is defined, @a n must
+ * be a numeric literal, not just a compile-time constant expression.
+ */
+#ifdef _WIN32
+#   define CILK_ALIGNAS(n) __declspec(align(n))
+#else /* Unix/gcc */
+#   define CILK_ALIGNAS(n) __attribute__((__aligned__(n)))
+#endif
+
+/**
+ * Macro to specify cache-line alignment of a data member in a structure.
+ */
+#define __CILKRTS_CACHE_ALIGN CILK_ALIGNAS(__CILKRTS_CACHE_LINE__)
+
+/**
+ * Macro to specify a class as being at least as strictly aligned as some
+ * type on Windows. gcc does not provide a way of doing this, so on Unix, 
+ * this just specifies the largest natural type alignment. Put the macro
+ * between the `class` keyword and the class name:
+ *
+ *      class CILK_ALIGNAS_TYPE(foo) bar { ... };
+ */
+#ifdef _WIN32
+#   define CILK_ALIGNAS_TYPE(t) __declspec(align(__alignof(t)))
+#else /* Unix/gcc */
+#   define CILK_ALIGNAS_TYPE(t) __attribute__((__aligned__))
+#endif
+
+/**
+ * @def CILK_API(RET_TYPE)
+ * A function called explicitly by the programmer.
+ * @def CILK_ABI(RET_TYPE)
+ * A function called by compiler-generated code.
+ * @def CILK_ABI_THROWS(RET_TYPE)
+ * An ABI function that may throw an exception
+ *
+ * Even when these are the same definitions, they should be separate macros so
+ * that they can be easily found in the code.
+ */
+
+#ifdef _WIN32
+#   define CILK_API(RET_TYPE) CILK_EXPORT RET_TYPE __CILKRTS_NOTHROW __cdecl
+#   define CILK_ABI(RET_TYPE) CILK_EXPORT RET_TYPE __CILKRTS_NOTHROW __cdecl
+#   define CILK_ABI_THROWS(RET_TYPE) CILK_EXPORT RET_TYPE __cdecl
+#else
+#   define CILK_API(RET_TYPE) CILK_EXPORT RET_TYPE __CILKRTS_NOTHROW
+#   define CILK_ABI(RET_TYPE) CILK_EXPORT RET_TYPE __CILKRTS_NOTHROW
+#   define CILK_ABI_THROWS(RET_TYPE) CILK_EXPORT RET_TYPE
+#endif
+
+/**
+ * __CILKRTS_ASSERT should be defined for debugging only, otherwise it
+ * interferes with vectorization.  Since NDEBUG is not reliable (it must be
+ * set by the user), we must use a platform-specific detection of debug mode.
+ */
+#if defined(_WIN32) && defined(_DEBUG)
+    /* Windows debug */
+#   define __CILKRTS_ASSERT(e) assert(e)
+#elif (! defined(_WIN32)) && ! defined(__OPTIMIZE__)
+    /* Unix non-optimized */
+#   define __CILKRTS_ASSERT(e) assert(e)
+#elif defined __cplusplus
+    /* C++ non-debug */
+#   define __CILKRTS_ASSERT(e) static_cast<void>(0)
+#else
+    /* C non-debug */
+#   define __CILKRTS_ASSERT(e) ((void) 0)
+#endif
+
+/**
+ * OS-independent macro to specify a function that should be inlined
+ */
+#ifdef __cpluspus
+    // C++
+#   define __CILKRTS_INLINE inline
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    // C99
+#   define __CILKRTS_INLINE static inline
+#elif defined(_MSC_VER)
+    // C89 on Windows
+#   define __CILKRTS_INLINE __inline
+#else
+    // C89 on GCC-compatible systems
+#   define __CILKRTS_INLINE extern __inline__
+#endif
+
+/**
+ * Functions marked as CILK_EXPORT_AND_INLINE have both
+ * inline versions defined in the Cilk API, as well as
+ * non-inlined versions that are exported (for
+ * compatibility with previous versions that did not
+ * inline the functions).
+ */
+#ifdef COMPILING_CILK_API_FUNCTIONS
+#   define CILK_EXPORT_AND_INLINE  CILK_EXPORT
+#else
+#   define CILK_EXPORT_AND_INLINE  __CILKRTS_INLINE
+#endif
+
+/**
+ * Try to determine if compiler supports rvalue references.
+ */
+#if defined(__cplusplus) && !defined(__CILKRTS_RVALUE_REFERENCES)
+#   if __cplusplus >= 201103L // C++11
+#       define __CILKRTS_RVALUE_REFERENCES 1
+#   elif defined(__GXX_EXPERIMENTAL_CXX0X__)
+#       define __CILKRTS_RVALUE_REFERENCES 1
+#   elif __cplusplus >= 199711L && __cplusplus < 201103L
+        // Compiler recognizes a language version prior to C++11
+#   elif __INTEL_COMPILER == 1200 && defined(__STDC_HOSTED__)
+        // Intel compiler version 12.0
+        // __cplusplus has a non-standard definition.  In the absence of a
+        // proper definition, look for the C++0x macro, __STDC_HOSTED__.
+#       define __CILKRTS_RVALUE_REFERENCES 1
+#   elif __INTEL_COMPILER > 1200 && defined(CHAR16T)
+        // Intel compiler version >= 12.1
+        // __cplusplus has a non-standard definition.  In the absence of a
+        // proper definition, look for the Intel macro, CHAR16T
+#       define __CILKRTS_RVALUE_REFERENCES 1
+#   endif
+#endif
+
+/*
+ * Include stdint.h to define the standard integer types.
+ *
+ * Unfortunately Microsoft doesn't provide stdint.h until Visual Studio 2010,
+ * so use our own definitions until those are available
+ */
+
+#if ! defined(_MSC_VER) || (_MSC_VER >= 1600)
+#   include <stdint.h>
+#else
+#   ifndef __MS_STDINT_TYPES_DEFINED__
+#       define __MS_STDINT_TYPES_DEFINED__
+        typedef signed char int8_t;
+        typedef short int16_t;
+        typedef int int32_t;
+        typedef __int64 int64_t;
+
+        typedef unsigned char uint8_t;
+        typedef unsigned short uint16_t;
+        typedef unsigned int uint32_t;
+        typedef unsigned __int64 uint64_t;
+#   endif  /* __MS_STDINT_TYPES_DEFINED__ */
+#endif  /* ! defined(_MSC_VER) || (_MSC_VER >= 1600) */
+
+/**
+ * @brief Application Binary Interface version of the Cilk runtime library.
+ *
+ * The ABI version is determined by the compiler used.  An object file
+ * compiled with a higher ABI version is not compatible with a library that is
+ * compiled with a lower ABI version.  An object file compiled with a lower
+ * ABI version, however, can be used with a library compiled with a higher ABI
+ * version unless otherwise stated.
+ */
+#ifndef __CILKRTS_ABI_VERSION
+#   ifdef IN_CILK_RUNTIME
+#       define __CILKRTS_ABI_VERSION 1
+#   elif __INTEL_COMPILER > 1200
+        // Intel compiler version >= 12.1
+#       define __CILKRTS_ABI_VERSION 1
+#   else
+        // Compiler does not support ABI version 1
+        // (Non-Intel compiler or Intel compiler prior to version 12.1).
+#       define __CILKRTS_ABI_VERSION 0
+#   endif
+#endif
+
+// These structs are exported because the inlining of
+// the internal version of API methods require a worker
+// structure as parameter. 
+__CILKRTS_BEGIN_EXTERN_C
+    /// Worker struct, exported for inlined API methods
+    /// @ingroup api
+    struct __cilkrts_worker;
+
+    /// Worker struct, exported for inlined API methods
+    /// @ingroup api
+    typedef struct __cilkrts_worker __cilkrts_worker;     
+
+    /// Worker struct pointer, exported for inlined API methods
+    /// @ingroup api
+    typedef struct __cilkrts_worker *__cilkrts_worker_ptr; 
+    
+    
+    /// Fetch the worker out of TLS.
+    CILK_ABI(__cilkrts_worker_ptr) __cilkrts_get_tls_worker(void);
+
+    /// void *, defined to work around complaints from the compiler
+    /// about using __declspec(nothrow) after the "void *" return type
+    typedef void * __cilkrts_void_ptr;
+
+__CILKRTS_END_EXTERN_C
+
+                                   
+#if __CILKRTS_ABI_VERSION >= 1
+// Pedigree API is available only for compilers that use ABI version >= 1.
+
+/** Pedigree information kept in the worker and stack frame.
+ *  @ingroup api
+ */
+typedef struct __cilkrts_pedigree
+{
+    /** Rank at start of spawn helper. Saved rank for spawning functions */
+    uint64_t rank;
+                                         
+    /** Link to next in chain */
+    const struct __cilkrts_pedigree *parent;
+} __cilkrts_pedigree;
+
+#endif // __CILKRTS_ABI_VERSION >= 1
+
+/// @}
+
+#endif /* INCLUDED_CILK_COMMON */
diff --git a/libcilkrts/include/cilk/holder.h b/libcilkrts/include/cilk/holder.h
new file mode 100644 (file)
index 0000000..8620c05
--- /dev/null
@@ -0,0 +1,1000 @@
+/*
+ *  @copyright
+ *  Copyright (C) 2011-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * holder.h
+ *
+ * Purpose: hyperobject to provide different views of an object to each
+ * parallel strand.
+ */
+
+#ifndef HOLDER_H_INCLUDED
+#define HOLDER_H_INCLUDED
+
+#include <cilk/reducer.h>
+#include <memory>
+#include <utility>
+
+#ifdef __cplusplus
+
+/* C++ Interface
+ *
+ * Classes: holder<Type>
+ *
+ * Description:
+ * ============
+ * This component provides a hyperobject that isolates a parallel uses of a
+ * common variable where it is not necessary to preserve changes from
+ * different parallel strands.  In effect, a holder acts a bit like
+ * thread-local storage, but has qualities that work better with the
+ * fork-join structure of Cilk.  In particular, a holder has the following
+ * qualities:
+ *
+ * - The view of a holder before the first spawn within a function is the same
+ *   as the view after each sync (as in the case of a reducer).
+ * - The view of a holder within the first spawned child of a function (or the
+ *   first child spawned after a sync) is the same as the view on entry to the
+ *   function.
+ * - The view of a holder before entering a _Cilk_for loop is the same as the
+ *   view during the first iteration of the loop and the view at the end of
+ *   the loop.
+ * - The view of a holder in the continuation of a spawn or in an arbitrary
+ *   iteration of a _Cilk_for loop is *non-deterministic*.  It is generally
+ *   recommended that the holder be explicitly put into a known state in these
+ *   situations.
+ *
+ * A holder can be used as an alternative to parameter-passing.  They are most
+ * useful for replacing non-local variables without massive refactoring.  A
+ * holder takes advantage of the fact that, most of the time, a holder view
+ * does not change after a spawn or from one iteration of a parallel for loop
+ * to the next (i.e., stealing is the exception, not the rule).  When the
+ * holder view is a large object that is expensive to construct, this
+ * optimization can save significant time versus creating a separate local
+ * object for each view.  In addition, a holder using the "keep last" policy
+ * will have the same value after a sync as the serialization of the same
+ * program.  The last quality will often allow the program to avoid
+ * recomputing a value.
+ *
+ * Usage Example:
+ * ==============
+ * Function 'compute()' is a complex function that computes a value using a
+ * memoized algorithm, storing intermediate results in a hash table.  Compute
+ * calls several other functions, each of which calls several other functions,
+ * all of which share a global hash table.  In all, there are over a dozen
+ * functions with a total of about 60 references to the hash table.  
+ *..
+ *  hash_table<int, X> memos;
+ *
+ *  void h(const X& x);  // Uses memos
+ *
+ *  double compute(const X& x)
+ *  {
+ *     memos.clear();
+ *     // ...
+ *     memos[i] = x;
+ *     ...
+ *     g(i);  // Uses memos
+ *     // ...
+ *     std::for_each(c.begin(), c.end(), h);  // Call h for each element of c
+ *  }
+ *
+ *  int main()
+ *  {
+ *      const std::size_t ARRAY_SIZE = 1000000;
+ *      extern X myArray[ARRAY_SIZE];
+ *
+ *      for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
+ *      {
+ *          compute(myArray[i]);
+ *      }
+ *  }
+ *..
+ * We would like to replace the 'for' loop in 'main' with a 'cilk_for'.
+ * Although the hash table is cleared on entry to each call to 'compute()',
+ * and although the values stored in the hash table are no longer used after
+ * 'compute()' returns, the use of the hash table as a global variable
+ * prevents 'compute()' from being called safely in parallel.  One way to do
+ * this would be to make 'memos' a private variable within the cilk_for loop
+ * and pass it down to the actual computation, so that each loop iteration has
+ * its own private copy:
+ *..
+ *      cilk_for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
+ *      {
+ *          hash_table<int, X> memos;
+ *          compute(myArray[i], memos);
+ *      }
+ *..
+ * The problem with this approach is that it requires changing the signature
+ * of 'compute', 'h', 'g', and every one of the dozen or so functions that
+ * reference 'memos' as well as any function that calls those functions.  This
+ * may break the abstraction of 'compute' and other functions, exposing an
+ * implementation detail that was not part of the interface.  In addition, the
+ * function 'h' is called through a templated algorithm, 'for_each', which
+ * requires a fixed interface.  Finally, there is constructor and destructor
+ * overhead for 'hash_table' each time through the loop.
+ *
+ * The alternative approach is to replace 'memos' with a holder.  The holder
+ * would be available to all of the functions involved, but would not cause a
+ * race between parallel loop iterations.  In order to make this work, each
+ * use of the 'memos' variable must be (mechanically) replaced by a use of the
+ * holder:
+ *..
+ *  cilk::holder<hash_table<int, X> > memos_h;
+ *
+ *  void h(const X& x);  // Uses memos_h
+ *
+ *  double compute(const X& x)
+ *  {
+ *     memos_h().clear();  // operator() used to "dereference" the holder
+ *     // ...
+ *     memos_h()[i] = x;   // operator() used to "dereference" the holder
+ *     ...
+ *     g(i);  // Uses memos_h
+ *     // ...
+ *     std::for_each(c.begin(), c.end(), h);  // Call h for each element of c
+ *  }
+ *..
+ * Note that each reference to the holder must be modified with an empty pair
+ * of parenthesis.  This syntax is needed because there is no facility in C++
+ * for a "smart reference" that would allow 'memos_h' to be a perfect
+ * replacement for 'memos'.  One way that a user can avoid this syntax change
+ * is to wrap the holder in a class that has the same inteface as
+ * 'hash_table' but redirects all calls to the holder:
+ *..
+ *  template <typename K, typename V>
+ *  class hash_table_holder
+ *  {
+ *    private:
+ *      cilk::holder<hash_table<K, V> > m_holder;
+ *    public:
+ *      void clear() { m_holder().clear(); }
+ *      V& operator[](const K& x) { return m_holder()[x]; }
+ *      std::size_t size() const { return m_holder().size(); }
+ *      // etc. ...
+ *  };
+ *..
+ * Using the above wrapper, the original code can be left unchanged except for
+ * replacing 'hash_table' with 'hash_table_holder' and replacing 'for' with
+ * 'cilk_for':
+ *..
+ *  hash_table_holder<int, X> memos;
+ *
+ *  void h(const X& x);  // Uses memos
+ *
+ *  double compute(const X& x)
+ *  {
+ *     memos.clear();  // Calls hash_table_holder::clear().
+ *     // ...
+ *  }
+ *..
+ * The above changes have no benefit over the use of thread-local storage.
+ * What if one of the functions has a 'cilk_spawn', however?
+ *..
+ *  void h(const X& x)
+ *  {
+ *      Y y = x.nested();
+ *      double d, w;
+ *      if (y)
+ *      {
+ *          w = cilk_spawn compute_width(y); // May use 'memos'
+ *          d = compute_depth(y);            // Does not use 'memos'
+ *          cilk_sync;
+ *          compute(y);  // recursive call.  Uses 'memos'.
+ *      }
+ *  }
+ *..
+ * In the above example, the view of the holder within 'compute_width' is the
+ * same as the view on entry to 'h'.  More importantly, the view of the holder
+ * within the recursive call to 'compute' is the same as the view on entry to
+ * 'h', even if a different worker is executing the recursive call.  Thus, the
+ * holder view within a Cilk program has useful qualities not found in
+ * thread-local storage.
+ */
+
+namespace cilk {
+    
+    /**
+     * After a sync, the value stored in a holder matches the most recent
+     * value stored into the holder by one of the starnds entering the sync.
+     * The holder policy used to instantiate the holder determines which of
+     * the entering strands determines the final value of the holder. A policy
+     * of 'holder_keep_indeterminate' (the default) is the most efficient, and
+     * results in an indeterminate value depending on the runtime schedule
+     * (see below for more specifics).  An indeterminate value after a sync is
+     * often acceptable, especially if the value of the holder is not reused
+     * after the sync.  All of the remaining policies retain the value of the
+     * last strand that would be executed in the serialization of the program.
+     * They differ in the mechanism used to move the value from one view to
+     * another.  A policy of 'holder_keep_last_copy' moves values by
+     * copy-assignment.  A policy of 'holder_keep_last_swap' moves values by
+     * calling 'swap'.  A policy of 'holder_keep_last_move' is available only
+     * for compilers that support C++0x rvalue references and moves values by
+     * move-assignment.  A policy of 'holder_keep_last' attempts to choose the
+     * most efficient mechanism: member-function 'swap' if the view type
+     * supports it, otherwise move-assignment if supported, otherwise
+     * copy-assignment.  (The swap member function for a class that provides
+     * one is almost always as fast or faster than move-assignment or
+     * copy-assignment.)
+     *
+     * The behavior of 'holder_keep_indeterminate', while indeterminate, is
+     * not random and can be used for advanced programming or debugging.  With
+     * a policy of 'holder_keep_intermediate', values are never copied or
+     * moved between views.  The value of the view after a sync is the same as
+     * the value set in the last spawned child before a steal occurs or the
+     * last value set in the continuation if no steal occurs.  Using this
+     * knowledge, a programmer can use a holder to detect the earliest steal
+     * in a piece of code.  An indeterminate holder is also useful for keeping
+     * cached data similar to the way some applications might use thread-local
+     * storage.
+     */
+    enum holder_policy {
+        holder_keep_indeterminate,
+        holder_keep_last,
+        holder_keep_last_copy,
+        holder_keep_last_swap,
+#ifdef __CILKRTS_RVALUE_REFERENCES
+        holder_keep_last_move
+#endif
+    };
+
+    namespace internal {
+
+        // Private special-case holder policy using the swap member-function
+        const holder_policy holder_keep_last_member_swap =
+            (holder_policy) (holder_keep_last_swap | 0x10);
+
+        /* The constant, 'has_member_swap<T>::value', will be 'true' if 'T'
+         * has a non-static member function with prototype 'void swap(T&)'.
+         * The mechanism used to detect 'swap' is the most portable among
+         * present-day compilers, but is not the most robust.  Specifically,
+         * the prototype for 'swap' must exactly match 'void swap(T&)'.
+         * Near-matches like a 'swap' function that returns 'int' instead of
+         * 'void' will not be detected.  Detection will also fail if 'T'
+         * inherits 'swap' from a base class.
+         */
+        template <typename T>
+        class has_member_swap
+        {
+            // This technique for detecting member functions was described by
+            // Rani Sharoni in comp.lang.c++.moderated:
+            // http://groups.google.com/group/comp.lang.c++.moderated/msg/2b06b2432fddfb60
+
+            // sizeof(notchar) is guaranteed larger than 1
+            struct notchar { char x[2]; };
+
+            // Instantiationg Q<U, &U::swap> will fail unless U contains a
+            // non-static member with prototype 'void swap(U&)'.
+            template <class U, void (U::*)(U&)> struct Q { };
+
+            // First 'test' is preferred overload if U::swap exists with the
+            // correct prototype.  Second 'test' is preferred overload
+            // otherwise.
+            template <typename U> static char test(Q<U,&U::swap>*);
+            template <typename U> static notchar test(...);
+
+        public:
+            /// 'value' will be true if T has a non-static member function
+            /// with prototype 'void swap(T&)'.
+            static const bool value = (1 == sizeof(test<T>(0)));
+        };
+
+        template <typename T> const bool has_member_swap<T>::value;
+
+        /**
+         * @brief Utility class for exception safety.
+         *
+         * The constuctor for this class takes a pointer and an allocator and
+         * holds on to them.  The destructor deallocates the pointed-to
+         * object, without calling its destructor, typically to recover memory
+         * in case an exception is thrown. The release member clears the
+         * pointer so that the deallocation is prevented, i.e., when the
+         * exception danger has passed.  The behavior of this class is similar
+         * to auto_ptr and unique_ptr.
+         */
+        template <typename Type, typename Allocator = std::allocator<Type> >
+        class auto_deallocator
+        {
+            Allocator m_alloc;
+            Type*     m_ptr;
+
+            // Non-copiable
+            auto_deallocator(const auto_deallocator&);
+            auto_deallocator& operator=(const auto_deallocator&);
+
+        public:
+            /// Constructor
+            explicit auto_deallocator(Type* p, const Allocator& a = Allocator())
+                : m_alloc(a), m_ptr(p) { }
+
+            /// Destructor - free allocated resources
+            ~auto_deallocator() { if (m_ptr) m_alloc.deallocate(m_ptr, 1); }
+
+            /// Remove reference to resource
+            void release() { m_ptr = 0; }
+        };
+
+        /**
+         * Pure-abstract base class to initialize holder views
+         */
+        template <typename Type, typename Allocator>
+        class init_base
+        {
+        public:
+            virtual ~init_base() { }
+            virtual init_base* clone_self(Allocator& a) const = 0;
+            virtual void delete_self(Allocator& a) = 0;
+            virtual void construct_view(Type* p, Allocator& a) const = 0;
+        };
+
+        /**
+         * Class to default-initialize a holder view
+         */
+        template <typename Type, typename Allocator>
+        class default_init : public init_base<Type, Allocator>
+        {
+            typedef init_base<Type, Allocator> base;
+
+            /// Private constructor (called from static make() function).
+            default_init() { }
+
+            // Non-copiable
+            default_init(const default_init&);
+            default_init& operator=(const default_init&);
+
+        public:
+            // Static factory function
+            static default_init* make(Allocator& a);
+
+            // Virtual function overrides
+            virtual ~default_init();
+            virtual base* clone_self(Allocator& a) const;
+            virtual void delete_self(Allocator& a);
+            virtual void construct_view(Type* p, Allocator& a) const;
+        };
+
+        template <typename Type, typename Allocator>
+        default_init<Type, Allocator>*
+        default_init<Type, Allocator>::make(Allocator&)
+        {
+            // Return a pointer to a singleton.  All instances of this class
+            // are identical, so we need only one.
+            static default_init self;
+            return &self;
+        }
+
+        template <typename Type, typename Allocator>
+        default_init<Type, Allocator>::~default_init()
+        {
+        }
+
+        template <typename Type, typename Allocator>
+        init_base<Type, Allocator>*
+        default_init<Type, Allocator>::clone_self(Allocator& a) const
+        {
+            return make(a);
+        }
+
+        template <typename Type, typename Allocator>
+        void default_init<Type, Allocator>::delete_self(Allocator&)
+        {
+            // Since make() returned a shared singleton, there is nothing to
+            // delete here.
+        }
+
+        template <typename Type, typename Allocator>
+        void
+        default_init<Type, Allocator>::construct_view(Type* p,
+                                                      Allocator&) const
+        {
+            ::new((void*) p) Type();
+            // TBD: In a C++0x library, this should be rewritten
+            // std::allocator_traits<Allocator>::construct(a, p);
+        }
+
+        /**
+         * Class to copy-construct a view from a stored exemplar.
+         */
+        template <typename Type, typename Allocator>
+        class exemplar_init : public init_base<Type, Allocator>
+        {
+            typedef init_base<Type, Allocator> base;
+
+            Type* m_exemplar;
+
+            // Private constructors (called from make() functions).
+            exemplar_init(const Type& val, Allocator& a);
+#ifdef __CILKRTS_RVALUE_REFERENCES
+            exemplar_init(Type&& val,      Allocator& a);
+#endif
+
+            // Non-copyiable
+            exemplar_init(const exemplar_init&);
+            exemplar_init& operator=(const exemplar_init&);
+
+        public:
+            // Static factory functions
+            static exemplar_init* make(const Type& val,
+                                       Allocator& a = Allocator());
+#ifdef __CILKRTS_RVALUE_REFERENCES
+            static exemplar_init* make(Type&& val,
+                                       Allocator& a = Allocator());
+#endif
+
+            // Virtual function overrides
+            virtual ~exemplar_init();
+            virtual base* clone_self(Allocator& a) const;
+            virtual void delete_self(Allocator& a);
+            virtual void construct_view(Type* p, Allocator& a) const;
+        };
+
+        template <typename Type, typename Allocator>
+        exemplar_init<Type, Allocator>::exemplar_init(const Type& val,
+                                                      Allocator&  a)
+        {
+            m_exemplar = a.allocate(1);
+            auto_deallocator<Type, Allocator> guard(m_exemplar, a);
+            a.construct(m_exemplar, val);
+            guard.release();
+        }
+
+#ifdef __CILKRTS_RVALUE_REFERENCES
+        template <typename Type, typename Allocator>
+        exemplar_init<Type, Allocator>::exemplar_init(Type&&     val,
+                                                      Allocator& a)
+        {
+            m_exemplar = a.allocate(1);
+            auto_deallocator<Type, Allocator> guard(m_exemplar, a);
+            a.construct(m_exemplar, std::forward<Type>(val));
+            guard.release();
+        }
+#endif
+
+        template <typename Type, typename Allocator>
+        exemplar_init<Type, Allocator>*
+        exemplar_init<Type, Allocator>::make(const Type& val,
+                                             Allocator&  a)
+        {
+            typedef typename Allocator::template rebind<exemplar_init>::other
+                self_alloc_t;
+            self_alloc_t alloc(a);
+
+            exemplar_init *self = alloc.allocate(1);
+            auto_deallocator<exemplar_init, self_alloc_t> guard(self, alloc);
+
+            // Don't use allocator to construct self.  Allocator should be
+            // used only on elements of type 'Type'.
+            ::new((void*) self) exemplar_init(val, a);
+
+            guard.release();
+
+            return self;
+        }
+
+#ifdef __CILKRTS_RVALUE_REFERENCES
+        template <typename Type, typename Allocator>
+        exemplar_init<Type, Allocator>*
+        exemplar_init<Type, Allocator>::make(Type&&           val,
+                                             Allocator& a)
+        {
+            typedef typename Allocator::template rebind<exemplar_init>::other
+                self_alloc_t;
+            self_alloc_t alloc(a);
+
+            exemplar_init *self = alloc.allocate(1);
+            auto_deallocator<exemplar_init, self_alloc_t> guard(self, alloc);
+
+            // Don't use allocator to construct self.  Allocator should be
+            // used only on elements of type 'Type'.
+            ::new((void*) self) exemplar_init(std::forward<Type>(val), a);
+
+            guard.release();
+
+            return self;
+        }
+#endif
+
+        template <typename Type, typename Allocator>
+        exemplar_init<Type, Allocator>::~exemplar_init()
+        {
+            // Called only by delete_self, which deleted the exemplar using an
+            // allocator.
+            __CILKRTS_ASSERT(0 == m_exemplar);
+        }
+
+        template <typename Type, typename Allocator>
+        init_base<Type, Allocator>*
+        exemplar_init<Type, Allocator>::clone_self(Allocator& a) const
+        {
+            return make(*m_exemplar, a);
+        }
+
+        template <typename Type, typename Allocator>
+        void exemplar_init<Type, Allocator>::delete_self(Allocator& a)
+        {
+            typename Allocator::template rebind<exemplar_init>::other alloc(a);
+
+            a.destroy(m_exemplar);
+            a.deallocate(m_exemplar, 1);
+            m_exemplar = 0;
+
+            this->~exemplar_init();
+            alloc.deallocate(this, 1);
+        }
+
+        template <typename Type, typename Allocator>
+        void
+        exemplar_init<Type, Allocator>::construct_view(Type*            p,
+                                                       Allocator& a) const
+        {
+            a.construct(p, *m_exemplar);
+            // TBD: In a C++0x library, this should be rewritten
+            // std::allocator_traits<Allocator>::construct(a, p, *m_exemplar);
+        }
+
+        /**
+         * Class to construct a view using a stored functor.  The functor,
+         * 'f', must be be invokable using the expression 'Type x = f()'.
+         */
+        template <typename Func, typename Allocator>
+        class functor_init :
+            public init_base<typename Allocator::value_type, Allocator>
+        {
+            typedef typename Allocator::value_type            value_type;
+            typedef init_base<value_type, Allocator>          base;
+            typedef typename Allocator::template rebind<Func>::other f_alloc;
+
+            Func *m_functor;
+
+            /// Private constructors (called from make() functions
+            functor_init(const Func& f, Allocator& a);
+#ifdef __CILKRTS_RVALUE_REFERENCES
+            functor_init(Func&& f, Allocator& a);
+#endif
+
+            // Non-copiable
+            functor_init(const functor_init&);
+            functor_init& operator=(const functor_init&);
+
+        public:
+            // Static factory functions
+            static functor_init* make(const Func& val,
+                                      Allocator& a = Allocator());
+#ifdef __CILKRTS_RVALUE_REFERENCES
+            static functor_init* make(Func&& val,
+                                      Allocator& a = Allocator());
+#endif
+
+            // Virtual function overrides
+            virtual ~functor_init();
+            virtual base* clone_self(Allocator& a) const;
+            virtual void delete_self(Allocator& a);
+            virtual void
+                construct_view(value_type* p, Allocator& a) const;
+        };
+
+        /// Specialization to strip off reference from 'Func&'.
+        template <typename Func, typename Allocator>
+        struct functor_init<Func&, Allocator>
+            : functor_init<Func, Allocator> { };
+
+        /// Specialization to strip off reference and cvq from 'const Func&'.
+        template <typename Func, typename Allocator>
+        struct functor_init<const Func&, Allocator>
+            : functor_init<Func, Allocator> { };
+
+        template <typename Func, typename Allocator>
+        functor_init<Func, Allocator>::functor_init(const Func& f,
+                                                    Allocator&  a)
+        {
+            f_alloc alloc(a);
+
+            m_functor = alloc.allocate(1);
+            auto_deallocator<Func, f_alloc> guard(m_functor, alloc);
+            alloc.construct(m_functor, f);
+            guard.release();
+        }
+
+#ifdef __CILKRTS_RVALUE_REFERENCES
+        template <typename Func, typename Allocator>
+        functor_init<Func, Allocator>::functor_init(Func&&     f,
+                                                    Allocator& a)
+        {
+            f_alloc alloc(a);
+
+            m_functor = alloc.allocate(1);
+            auto_deallocator<Func, f_alloc> guard(m_functor, alloc);
+            alloc.construct(m_functor, std::forward<Func>(f));
+            guard.release();
+        }
+#endif
+
+        template <typename Func, typename Allocator>
+        functor_init<Func, Allocator>*
+        functor_init<Func, Allocator>::make(const Func& f, Allocator& a)
+        {
+            typedef typename Allocator::template rebind<functor_init>::other
+                self_alloc_t;
+            self_alloc_t alloc(a);
+
+            functor_init *self = alloc.allocate(1);
+            auto_deallocator<functor_init, self_alloc_t> guard(self, alloc);
+
+            // Don't use allocator to construct self.  Allocator should be
+            // used only on elements of type 'Func'.
+            ::new((void*) self) functor_init(f, a);
+
+            guard.release();
+
+            return self;
+        }
+
+#ifdef __CILKRTS_RVALUE_REFERENCES
+        template <typename Func, typename Allocator>
+        functor_init<Func, Allocator>*
+        functor_init<Func, Allocator>::make(Func&& f, Allocator& a)
+        {
+            typedef typename Allocator::template rebind<functor_init>::other
+                self_alloc_t;
+            self_alloc_t alloc(a);
+
+            functor_init *self = alloc.allocate(1);
+            auto_deallocator<functor_init, self_alloc_t> guard(self, alloc);
+
+            // Don't use allocator to construct self.  Allocator should be
+            // used only on elements of type 'Func'.
+            ::new((void*) self) functor_init(std::forward<Func>(f), a);
+
+            guard.release();
+
+            return self;
+        }
+#endif
+
+        template <typename Func, typename Allocator>
+        functor_init<Func, Allocator>::~functor_init()
+        {
+            // Called only by delete_self, which deleted the functor using an
+            // allocator.
+            __CILKRTS_ASSERT(0 == m_functor);
+        }
+
+        template <typename Func, typename Allocator>
+        init_base<typename Allocator::value_type, Allocator>*
+        functor_init<Func, Allocator>::clone_self(Allocator& a) const
+        {
+            return make(*m_functor, a);
+        }
+
+        template <typename Func, typename Allocator>
+        inline
+        void functor_init<Func, Allocator>::delete_self(Allocator& a)
+        {
+            typename Allocator::template rebind<functor_init>::other alloc(a);
+            f_alloc fa(a);
+
+            fa.destroy(m_functor);
+            fa.deallocate(m_functor, 1);
+            m_functor = 0;
+
+            this->~functor_init();
+            alloc.deallocate(this, 1);
+        }
+
+        template <typename Func, typename Allocator>
+        void functor_init<Func, Allocator>::construct_view(value_type* p,
+                                                           Allocator& a) const
+        {
+            a.construct(p, (*m_functor)());
+            // In C++0x, the above should be written
+            // std::allocator_traits<Allocator>::construct(a, p, m_functor());
+        }
+
+        /**
+         * Functor called to reduce a holder
+         */
+        template <typename Type, holder_policy Policy>
+        struct holder_reduce_functor;
+
+        /**
+         * Specialization to keep the left (first) value.
+         */
+        template <typename Type>
+        struct holder_reduce_functor<Type, holder_keep_indeterminate>
+        {
+            void operator()(Type* left, Type* right) const { }
+        };
+
+        /**
+         * Specialization to copy-assign from the right (last) value.
+         */
+        template <typename Type>
+        struct holder_reduce_functor<Type, holder_keep_last_copy>
+        {
+            void operator()(Type* left, Type* right) const {
+                *left = *right;
+            }
+        };
+
+        /*
+         * Specialization to keep the right (last) value via swap.
+         */
+        template <typename Type>
+        struct holder_reduce_functor<Type, holder_keep_last_swap>
+        {
+            void operator()(Type* left, Type* right) const {
+                using std::swap;
+                swap(*left, *right);
+            }
+        };
+
+#ifdef __CILKRTS_RVALUE_REFERENCES
+        /*
+         * Specialization to move-assign from the right (last) value.
+         */
+        template <typename Type>
+        struct holder_reduce_functor<Type, holder_keep_last_move>
+        {
+            void operator()(Type* left, Type* right) const {
+                *left = std::move(*right);
+            }
+        };
+#endif
+
+        /*
+         * Specialization to keep the right (last) value via the swap member
+         * function.
+         */
+        template <typename Type>
+        struct holder_reduce_functor<Type, holder_keep_last_member_swap>
+        {
+            void operator()(Type* left, Type* right) const {
+                left->swap(*right);
+            }
+        };
+
+        /*
+         * Specialization to keep the right (last) value by the most efficient
+         * means detectable.
+         */
+        template <typename Type>
+        struct holder_reduce_functor<Type, holder_keep_last> :
+            holder_reduce_functor<Type,
+                                  (holder_policy)
+                                  (has_member_swap<Type>::value ?
+                                  holder_keep_last_member_swap :
+#ifdef __CILKRTS_RVALUE_REFERENCES
+                                  holder_keep_last_move
+#else
+                                  holder_keep_last_copy
+#endif
+                                  )>
+        {
+        };
+    } // end namespace internal
+
+    /**
+     * Monoid for holders.
+     * Allocator type is required to be thread-safe.
+     */
+    template <typename Type,
+              holder_policy Policy = holder_keep_indeterminate,
+              typename Allocator = std::allocator<Type> >
+    class holder_monoid : public monoid_base<Type>
+    {
+        // Allocator is mutable because the copy of the monoid inside the
+        // reducer is const (to avoid races on the shared state).  However,
+        // the allocator is required to be thread-safe, so it is ok (and
+        // necessary) to modify.
+        mutable Allocator                     m_allocator;
+        internal::init_base<Type, Allocator> *m_initializer;
+
+    public:
+        /// This constructor uses default-initialization for both the leftmost
+        /// view and each identity view.
+        holder_monoid(const Allocator& a = Allocator())
+            : m_allocator(a)
+            , m_initializer(
+                internal::default_init<Type, Allocator>::make(m_allocator))
+            { }
+
+        /// These constructors use 'val' as an exemplar to copy-construct both
+        /// the leftmost view and each identity view.
+        holder_monoid(const Type& val, const Allocator& a = Allocator())
+            : m_allocator(a)
+            , m_initializer(internal::exemplar_init<Type, Allocator>::make(
+                                val, m_allocator)) { }
+        /// This constructor uses 'f' as a functor to construct both
+        /// the leftmost view and each identity view.
+        template <typename Func>
+        holder_monoid(const Func& f, const Allocator& a = Allocator())
+            : m_allocator(a)
+            , m_initializer(
+                internal::functor_init<Func, Allocator>::make(f,m_allocator))
+            { }
+
+        /// Copy constructor
+        holder_monoid(const holder_monoid& rhs)
+            : m_allocator(rhs.m_allocator)
+            , m_initializer(rhs.m_initializer->clone_self(m_allocator)) { }
+
+        /// "Extended" copy constructor with allocator
+        holder_monoid(const holder_monoid& rhs, const Allocator& a)
+            : m_allocator(a)
+            , m_initializer(rhs.m_initializer->clone_self(m_allocator)) { }
+
+#ifdef __CILKRTS_RVALUE_REFERENCES
+        /// Move constructor
+        holder_monoid(holder_monoid&& rhs)
+            : m_allocator(rhs.m_allocator)
+            , m_initializer(rhs.m_initializer) {
+            rhs.m_initializer =
+                internal::default_init<Type, Allocator>::make(m_allocator);
+        }
+
+        /// "Extended" move constructor with allocator
+        holder_monoid(holder_monoid&& rhs, const Allocator& a)
+            : m_allocator(a)
+            , m_initializer(0) {
+            if (a != rhs.m_allocator)
+                m_initializer = rhs.m_initializer->clone_self(a);
+            else {
+                m_initializer = rhs.m_initializer;
+                rhs.m_initializer =
+                    internal::default_init<Type, Allocator>::make(m_allocator);
+            }
+        }
+#endif
+        /// Destructor
+        ~holder_monoid() { m_initializer->delete_self(m_allocator); }
+
+        holder_monoid& operator=(const holder_monoid& rhs) {
+            if (this == &rhs) return *this;
+            m_initializer->delete_self(m_allocator);
+            m_initializer = rhs.m_initializer->clone_self(m_allocator);
+        }
+
+#ifdef __CILKRTS_RVALUE_REFERENCES
+        holder_monoid& operator=(holder_monoid&& rhs) {
+            if (m_allocator != rhs.m_allocator)
+                // Delegate to copy-assignment on unequal allocators
+                return operator=(static_cast<const holder_monoid&>(rhs));
+            std::swap(m_initializer, rhs.m_initializer);
+            return *this;
+        }
+#endif
+
+        /// Constructs IDENTITY value into the uninitilized '*p'
+        void identity(Type* p) const
+            { m_initializer->construct_view(p, m_allocator); }
+
+        /// Calls the destructor on the object pointed-to by 'p'
+        void destroy(Type* p) const
+            { m_allocator.destroy(p); }
+
+        /// Return a pointer to size bytes of raw memory
+        void* allocate(std::size_t s) const {
+            __CILKRTS_ASSERT(sizeof(Type) == s);
+            return m_allocator.allocate(1);
+        }
+
+        /// Deallocate the raw memory at p
+        void deallocate(void* p) const {
+            m_allocator.deallocate(static_cast<Type*>(p), sizeof(Type));
+        }
+
+        void reduce(Type* left, Type* right) const {
+            internal::holder_reduce_functor<Type, Policy>()(left, right);
+        }
+
+        void swap(holder_monoid& other) {
+            __CILKRTS_ASSERT(m_allocator == other.m_allocator);
+            std::swap(m_initializer, other.m_initializer);
+        }
+
+        Allocator get_allocator() const {
+            return m_allocator;
+        }
+    };
+
+    // Namespace-scope swap
+    template <typename Type, holder_policy Policy, typename Allocator>
+    inline void swap(holder_monoid<Type, Policy, Allocator>& a,
+                     holder_monoid<Type, Policy, Allocator>& b)
+    {
+        a.swap(b);
+    }
+
+   /**
+    * Hyperobject to provide different views of an object to each
+    * parallel strand.
+    */
+    template <typename Type,
+              holder_policy Policy = holder_keep_indeterminate,
+              typename Allocator = std::allocator<Type> >
+    class holder : public reducer<holder_monoid<Type, Policy, Allocator> >
+    {
+        typedef holder_monoid<Type, Policy, Allocator> monoid_type;
+        typedef reducer<monoid_type> imp;
+
+        // Return a value of Type constructed using the functor Func.
+        template <typename Func>
+        Type make_value(const Func& f) const {
+            struct obj {
+                union {
+                    char buf[sizeof(Type)];
+                    void* align1;
+                    double align2;
+                };
+
+                obj(const Func& f) { f(static_cast<Type*>(buf)); }
+                ~obj() { static_cast<Type*>(buf)->~Type(); }
+
+                operator Type&() { return *static_cast<Type*>(buf); }
+            };
+
+            return obj(f);
+        }
+
+    public:
+        /// Default constructor uses default-initialization for both the
+        /// leftmost view and each identity view.
+        holder(const Allocator& alloc = Allocator())
+            : imp(monoid_type(alloc)) { }
+
+        /// Construct from an exemplar that is used to initialize both the
+        /// leftmost view and each identity view.
+        holder(const Type& v, const Allocator& alloc = Allocator())
+            // Alas, cannot use an rvalue reference for 'v' because it is used
+            // twice in the same expression for initializing imp.
+            : imp(monoid_type(v, alloc), v) { }
+
+        /// Construct from a functor that is used to initialize both the
+        /// leftmost view and each identity view.  The functor, 'f', must be be
+        /// invokable using the expression 'Type x = f()'.
+        template <typename Func>
+        holder(const Func& f, const Allocator& alloc = Allocator())
+            // Alas, cannot use an rvalue for 'f' because it is used twice in
+            // the same expression for initializing imp.
+            : imp(monoid_type(f, alloc), make_value(f)) { }
+    };
+
+} // end namespace cilk
+
+#else /* C */
+# error Holders are currently available only for C++
+#endif /* __cplusplus */
+
+#endif /* HOLDER_H_INCLUDED */
diff --git a/libcilkrts/include/cilk/hyperobject_base.h b/libcilkrts/include/cilk/hyperobject_base.h
new file mode 100644 (file)
index 0000000..484bf5f
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_CILK_HYPEROBJECT_BASE
+#define INCLUDED_CILK_HYPEROBJECT_BASE
+
+#ifdef __cplusplus
+# include <cstdlib>
+# include <cstddef>
+#else
+# include <stdlib.h>
+# include <stddef.h>
+#endif
+
+#include <cilk/common.h>
+
+#if defined _WIN32 || defined _WIN64
+# if !defined CILK_STUB && !defined IN_CILK_RUNTIME
+    /* bring in the Cilk library, which has definitions for some of these
+     * functions. */
+#   pragma comment(lib, "cilkrts")
+# endif
+#endif
+
+/* The __CILKRTS_STRAND_PURE attribute tells the compiler that the value
+ * returned by 'func' for a given argument to 'func' will remain valid until
+ * the next strand boundary (spawn or sync) or until the next call to a
+ * function with the __CILKRTS_STRAND_STALE attribute using the same function
+ * argument.
+ */
+#if 0 && defined __cilk && (defined __GNUC__ && !defined _WIN32) && defined __cilkartsrev
+# define __CILKRTS_STRAND_PURE(func) \
+    func __attribute__((__cilk_hyper__("lookup")))
+# define __CILKRTS_STRAND_STALE(func) \
+    func __attribute__((__cilk_hyper__("flush")))
+#else
+# define __CILKRTS_STRAND_PURE(func) func
+# define __CILKRTS_STRAND_STALE(func) func
+#endif
+
+/*****************************************************************************
+ * C runtime interface to the hyperobject subsystem
+ *****************************************************************************/
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/* Callback function signatures.  The 'r' argument always points to the
+ * reducer itself and is commonly ignored. */
+typedef void (*cilk_c_reducer_reduce_fn_t)(void* r, void* lhs, void* rhs);
+typedef void (*cilk_c_reducer_identity_fn_t)(void* r, void* view);
+typedef void (*cilk_c_reducer_destroy_fn_t)(void* r, void* view);
+typedef void* (*cilk_c_reducer_allocate_fn_t)(void* r, __STDNS size_t bytes);
+typedef void (*cilk_c_reducer_deallocate_fn_t)(void* r, void* view);
+
+/** Representation of the monoid */
+typedef struct cilk_c_monoid {
+    cilk_c_reducer_reduce_fn_t          reduce_fn;
+    cilk_c_reducer_identity_fn_t        identity_fn;
+    cilk_c_reducer_destroy_fn_t         destroy_fn;
+    cilk_c_reducer_allocate_fn_t        allocate_fn;
+    cilk_c_reducer_deallocate_fn_t      deallocate_fn;
+} cilk_c_monoid;
+
+/** Base of the hyperobject */
+typedef struct __cilkrts_hyperobject_base
+{
+    cilk_c_monoid       __c_monoid;
+    unsigned long long  __flags;
+    __STDNS ptrdiff_t   __view_offset;  /* offset (in bytes) to leftmost view */
+    __STDNS size_t      __view_size;    /* Size of each view */
+} __cilkrts_hyperobject_base;
+
+
+#ifndef CILK_STUB
+
+/* Library functions. */
+CILK_EXPORT
+    void __cilkrts_hyper_create(__cilkrts_hyperobject_base *key);
+CILK_EXPORT void __CILKRTS_STRAND_STALE(
+    __cilkrts_hyper_destroy(__cilkrts_hyperobject_base *key));
+CILK_EXPORT void* __CILKRTS_STRAND_PURE(
+    __cilkrts_hyper_lookup(__cilkrts_hyperobject_base *key));
+
+CILK_EXPORT
+    void* __cilkrts_hyperobject_alloc(void* ignore, __STDNS size_t bytes);
+CILK_EXPORT
+    void __cilkrts_hyperobject_dealloc(void* ignore, void* view);
+
+/* No-op destroy function */
+CILK_EXPORT
+    void __cilkrts_hyperobject_noop_destroy(void* ignore, void* ignore2);
+
+
+#else // CILK_STUB
+
+// Programs compiled with CILK_STUB are not linked with the Cilk runtime 
+// library, so they should not have external references to cilkrts functions.
+// Furthermore, they don't need the hyperobject functionality, so the
+// functions can be stubbed.
+
+#define __cilkrts_hyperobject_create __cilkrts_hyperobject_create__stub
+__CILKRTS_INLINE
+    void __cilkrts_hyper_create(__cilkrts_hyperobject_base *key) 
+    {}
+
+#define __cilkrts_hyperobject_destroy __cilkrts_hyperobject_destroy__stub
+__CILKRTS_INLINE
+    void __cilkrts_hyper_destroy(__cilkrts_hyperobject_base *key) 
+    {}
+
+#define __cilkrts_hyperobject_lookup __cilkrts_hyperobject_lookup__stub
+__CILKRTS_INLINE
+    void* __cilkrts_hyper_lookup(__cilkrts_hyperobject_base *key)
+    { return (char*)(key) + key->__view_offset; }
+
+// Pointers to these functions are stored into monoids, so real functions
+// are needed.
+
+#define __cilkrts_hyperobject_alloc __cilkrts_hyperobject_alloc__stub
+__CILKRTS_INLINE
+    void* __cilkrts_hyperobject_alloc(void* ignore, __STDNS size_t bytes)
+    { assert(0); return __STDNS malloc(bytes); }
+
+#define __cilkrts_hyperobject_dealloc __cilkrts_hyperobject_dealloc__stub
+__CILKRTS_INLINE
+    void __cilkrts_hyperobject_dealloc(void* ignore, void* view)
+    { assert(0); __STDNS free(view); }
+
+#define __cilkrts_hyperobject_noop_destroy \
+            __cilkrts_hyperobject_noop_destroy__stub
+__CILKRTS_INLINE
+    void __cilkrts_hyperobject_noop_destroy(void* ignore, void* ignore2)
+    {}
+    
+#endif
+
+__CILKRTS_END_EXTERN_C
+
+#endif /* INCLUDED_CILK_HYPEROBJECT_BASE */
diff --git a/libcilkrts/include/cilk/metaprogramming.h b/libcilkrts/include/cilk/metaprogramming.h
new file mode 100644 (file)
index 0000000..5f6f29d
--- /dev/null
@@ -0,0 +1,606 @@
+/*  metaprogramming.h                  -*- C++ -*-
+ *
+ *  @copyright
+ *  Copyright (C) 2012-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file metaprogramming.h
+ *
+ *  @brief Defines metaprogramming utility classes used in the Cilk library.
+ *
+ *  @ingroup common
+ */
+
+#ifndef METAPROGRAMMING_H_INCLUDED
+#define METAPROGRAMMING_H_INCLUDED
+
+#ifdef __cplusplus
+
+#include <functional>
+#include <new>
+#include <cstdlib>
+#ifdef _WIN32
+#include <malloc.h>
+#endif
+#include <algorithm>
+
+namespace cilk {
+
+namespace internal {
+
+/** Test if a class is empty.
+ *
+ *  If @a Class is an empty (and therefore necessarily stateless) class, then
+ *  the “empty base-class optimization” guarantees that
+ *  `sizeof(check_for_empty_class<Class>) == sizeof(char)`. Conversely, if
+ *  `sizeof(check_for_empty_class<Class>) > sizeof(char)`, then @a Class is not
+ *  empty, and we must discriminate distinct instances of @a Class.
+ *
+ *  Typical usage:
+ *
+ *      // General definition of A<B> for non-empty B:
+ *      template <typename B, bool BIsEmpty = class_is_empty<B>::value> >
+ *      class A { ... };
+ *
+ *      // Specialized definition of A<B> for empty B:
+ *      template <typename B>
+ *      class A<B, true> { ... };
+ *
+ *  @tparam Class   The class to be tested for emptiness.
+ *
+ *  @result         The `value` member will be `true` if @a Class is empty,
+ *                  `false` otherwise.
+ *
+ *  @ingroup common
+ */
+template <class Class>
+class class_is_empty { 
+    class check_for_empty_class : public Class
+    {
+        char m_data;
+    public:
+        // Declared but not defined
+        check_for_empty_class();
+        check_for_empty_class(const check_for_empty_class&);
+        check_for_empty_class& operator=(const check_for_empty_class&);
+        ~check_for_empty_class();
+    };
+public:
+
+    /** Constant is true if and only if @a Class is empty.
+     */
+    static const bool value = (sizeof(check_for_empty_class) == sizeof(char));
+};
+
+
+/** Get the alignment of a type.
+ *
+ *  For example:
+ *
+ *      align_of<double>::value == 8
+ *
+ *  @tparam Tp  The type whose alignment is to be computed.
+ *
+ *  @result     The `value` member of an instantiation of this class template
+ *              will hold the integral alignment requirement of @a Tp.
+ *
+ *  @pre        @a Tp shall be a complete type.
+ *
+ *  @ingroup common
+ */
+template <typename Tp>
+struct align_of
+{
+private:
+    struct imp {
+        char m_padding;
+        Tp   m_val;
+
+        // The following declarations exist to suppress compiler-generated
+        // definitions, in case @a Tp does not have a public default
+        // constructor, copy constructor, or destructor.
+        imp(const imp&); // Declared but not defined
+        ~imp();          // Declared but not defined
+    };
+
+public:
+    /// The integral alignment requirement of @a Tp.
+    static const std::size_t    value = (sizeof(imp) - sizeof(Tp));
+};
+
+
+/** A class containing raw bytes with a specified alignment and size.
+ *
+ *  An object of type `aligned_storage<S, A>` will have alignment `A` and
+ *  size at least `S`. Its contents will be uninitialized bytes.
+ *
+ *  @tparam Size        The required minimum size of the resulting class.
+ *  @tparam Alignment   The required alignment of the resulting class.
+ *
+ *  @pre    @a Alignment shall be a power of 2 no greater then 64.
+ *
+ *  @note   This is implemented using the `CILK_ALIGNAS` macro, which uses
+ *          the non-standard, implementation-specific features
+ *          `__declspec(align(N))` on Windows, and 
+ *          `__attribute__((__aligned__(N)))` on Unix. The `gcc` implementation
+ *          of `__attribute__((__aligned__(N)))` requires a numeric literal `N`
+ *          (_not_ an arbitrary compile-time constant expression). Therefore,
+ *          this class is implemented using specialization on the required
+ *          alignment.
+ *
+ *  @note   The template class is specialized only for the supported
+ *          alignments. An attempt to instantiate it for an unsupported
+ *          alignment will result in a compilation error.
+ */
+template <std::size_t Size, std::size_t Alignment>
+struct aligned_storage;
+
+template<std::size_t Size> class aligned_storage<Size,  1> 
+    { CILK_ALIGNAS( 1) char m_bytes[Size]; };
+template<std::size_t Size> class aligned_storage<Size,  2> 
+    { CILK_ALIGNAS( 2) char m_bytes[Size]; };
+template<std::size_t Size> class aligned_storage<Size,  4> 
+    { CILK_ALIGNAS( 4) char m_bytes[Size]; };
+template<std::size_t Size> class aligned_storage<Size,  8> 
+    { CILK_ALIGNAS( 8) char m_bytes[Size]; };
+template<std::size_t Size> class aligned_storage<Size, 16> 
+    { CILK_ALIGNAS(16) char m_bytes[Size]; };
+template<std::size_t Size> class aligned_storage<Size, 32> 
+    { CILK_ALIGNAS(32) char m_bytes[Size]; };
+template<std::size_t Size> class aligned_storage<Size, 64> 
+    { CILK_ALIGNAS(64) char m_bytes[Size]; };
+
+
+/** A buffer of uninitialized bytes with the same size and alignment as a
+ *  specified type.
+ *
+ *  The class `storage_for_object<Type>` will have the same size and alignment
+ *  properties as `Type`, but it will contain only raw (uninitialized) bytes.
+ *  This allows the definition of a data member which can contain a `Type`
+ *  object which is initialized explicitly under program control, rather
+ *  than implicitly as part of the initialization of the containing class. 
+ *  For example:
+ *
+ *      class C {
+ *          storage_for_object<MemberClass> _member;
+ *      public:
+ *          C() ... // Does NOT initialize _member
+ *          void initialize(args) 
+ *              { new (_member.pointer()) MemberClass(args); }
+ *          const MemberClass& member() const { return _member.object(); }
+ *                MemberClass& member()       { return _member.object(); }
+ *
+ *  @tparam Type    The type whose size and alignment are to be reflected
+ *                  by this class.
+ */
+template <typename Type>
+class storage_for_object : 
+    aligned_storage< sizeof(Type), align_of<Type>::value >
+{
+public:
+    /// Return a typed reference to the buffer.
+    const Type& object() const { return *reinterpret_cast<Type*>(this); }
+          Type& object()       { return *reinterpret_cast<Type*>(this); }
+};
+
+
+/** Get the functor class corresponding to a binary function type.
+ *
+ *  The `binary_functor` template class class can be instantiated with a binary
+ *  functor class or with a real binary function, and will yield an equivalent
+ *  binary functor class class in either case.
+ *
+ *  @tparam F   A binary functor class, a binary function type, or a pointer to
+ *              binary function type.
+ *
+ *  @result     `binary_functor<F>::%type` will be the same as @a F if @a F is
+ *              a class. It will be a `std::pointer_to_binary_function` wrapper
+ *              if @a F is a binary function or binary function pointer type.
+ *              (It will _not_ necessarily be an `Adaptable Binary Function`
+ *              class, since @a F might be a non-adaptable binary functor
+ *              class.)
+ *
+ *  @ingroup common
+ */
+template <typename F>
+struct binary_functor {
+     /// The binary functor class equivalent to @a F.
+     typedef F type;
+};
+
+/// @copydoc binary_functor
+/// Specialization for binary function.
+template <typename R, typename A, typename B>
+struct binary_functor<R(A,B)> {
+     /// The binary functor class equivalent to @a F.
+    typedef std::pointer_to_binary_function<A, B, R> type;
+};
+
+/// @copydoc binary_functor
+/// Specialization for pointer to binary function.
+template <typename R, typename A, typename B>
+struct binary_functor<R(*)(A,B)> {
+     /// The binary functor class equivalent to @a F.
+    typedef std::pointer_to_binary_function<A, B, R> type;
+};
+
+
+/** Indirect binary function class with specified types.
+ *
+ *  `typed_indirect_binary_function<F>` is an `Adaptable Binary Function` class
+ *  based on an existing binary functor class or binary function type @a F. If
+ *  @a F is a stateless class, then this class will be empty, and its
+ *  `operator()` will invoke @a F’s `operator()`. Otherwise, an object of this
+ *  class will hold a pointer to an object of type @a F, and will refer its
+ *  `operator()` calls to the pointed-to @a F object.
+ *
+ *  That is, suppose that we have the declarations:
+ *
+ *      F *p;
+ *      typed_indirect_binary_function<F, int, int, bool> ibf(p);
+ *
+ *  Then:
+ *
+ *  -   `ibf(x, y) == (*p)(x, y)`.
+ *  -   `ibf(x, y)` will not do a pointer dereference if `F` is an empty class.
+ *
+ *  @note       Just to repeat: if `F` is an empty class, then
+ *              `typed_indirect_binary_function\<F\>' is also an empty class.
+ *              This is critical for its use in the @ref min_max::view_base
+ *              "min/max reducer view classes", where it allows the view to
+ *              call a comparison functor in the monoid without actually
+ *              having to allocate a pointer in the view class when the 
+ *              comparison class is empty.
+ *
+ *  @note       If you have an `Adaptable Binary Function` class or a binary
+ *              function type, then you can use the 
+ *              @ref indirect_binary_function class, which derives the
+ *              argument and result types parameter type instead of requiring
+ *              you to specify them as template arguments.
+ *
+ *  @tparam F   A binary functor class, a binary function type, or a pointer to
+ *              binary function type.
+ *  @param A1   The first argument type.
+ *  @param A2   The second argument type.
+ *  @param R    The result type.
+ *
+ *  @see min_max::comparator_base
+ *  @see indirect_binary_function
+ *
+ *  @ingroup common
+ */
+template <  typename F
+         ,  typename A1
+         ,  typename A2
+         ,  typename R
+         ,  typename Functor    = typename binary_functor<F>::type
+         ,  bool FunctorIsEmpty = class_is_empty<Functor>::value
+         >
+class typed_indirect_binary_function : std::binary_function<A1, A2, R>
+{
+    const F* f;
+public:
+    /// Constructor captures a pointer to the wrapped function.
+    typed_indirect_binary_function(const F* f) : f(f) {}
+    
+    /// Return the comparator pointer, or `NULL` if the comparator is stateless.
+    const F* pointer() const { return f; }
+
+    /// Apply the pointed-to functor to the arguments.
+    R operator()(const A1& a1, const A2& a2) const { return (*f)(a1, a2); }
+};
+
+
+/// @copydoc typed_indirect_binary_function
+/// Specialization for an empty functor class. (This is only possible if @a F
+/// itself is an empty class. If @a F is a function or pointer-to-function 
+/// type, then the functor will contain a pointer.)
+template <typename F, typename A1, typename A2, typename R, typename Functor>
+class typed_indirect_binary_function<F, A1, A2, R, Functor, true> : 
+    std::binary_function<A1, A2, R>
+{
+public:
+    /// Return `NULL` for the comparator pointer of a stateless comparator.
+    const F* pointer() const { return 0; }
+
+    /// Constructor discards the pointer to a stateless functor class.
+    typed_indirect_binary_function(const F* f) {}
+    
+    /// Create an instance of the stateless functor class and apply it to the arguments.
+    R operator()(const A1& a1, const A2& a2) const { return F()(a1, a2); }
+};
+
+
+/** Indirect binary function class with inferred types.
+ *
+ *  This is identical to @ref typed_indirect_binary_function, except that it
+ *  derives the binary function argument and result types from the parameter
+ *  type @a F instead of taking them as additional template parameters. If @a F
+ *  is a class type, then it must be an `Adaptable Binary Function`.
+ *
+ *  @see typed_indirect_binary_function
+ *
+ *  @ingroup common
+ */
+template <typename F, typename Functor = typename binary_functor<F>::type>
+class indirect_binary_function : 
+    typed_indirect_binary_function< F
+                                  , typename Functor::first_argument_type
+                                  , typename Functor::second_argument_type
+                                  , typename Functor::result_type
+                                  > 
+{
+    typedef     typed_indirect_binary_function< F
+                                  , typename Functor::first_argument_type
+                                  , typename Functor::second_argument_type
+                                  , typename Functor::result_type
+                                  > 
+                base;
+public:
+    indirect_binary_function(const F* f) : base(f) {} ///< Constructor
+};
+
+
+/** Choose a type based on a boolean constant.
+ *
+ *  This metafunction is identical to C++11’s condition metafunction.
+ *  It needs to be here until we can reasonably assume that users will be
+ *  compiling with C++11.
+ *
+ *  @tparam Cond    A boolean constant.
+ *  @tparam IfTrue  A type.
+ *  @tparam IfFalse A type.
+ *  @result         The `type` member will be a typedef of @a IfTrue if @a Cond
+ *                  is true, and a typedef of @a IfFalse if @a Cond is false.
+ *
+ *  @ingroup common
+ */
+template <bool Cond, typename IfTrue, typename IfFalse>
+struct condition
+{
+    typedef IfTrue type;    ///< The type selected by the condition.
+};
+
+/// @copydoc condition
+/// Specialization for @a Cond == `false`.
+template <typename IfTrue, typename IfFalse>
+struct condition<false, IfTrue, IfFalse>
+{
+    typedef IfFalse type;   ///< The type selected by the condition.
+};
+
+
+/** @def __CILKRTS_STATIC_ASSERT
+ *
+ *  @brief Compile-time assertion.
+ *
+ *  Causes a compilation error if a compile-time constant expression is false.
+ *
+ *  @par    Usage example.
+ *          This assertion  is used in reducer_min_max.h to avoid defining 
+ *          legacy reducer classes that would not be binary-compatible with the
+ *          same classes compiled with earlier versions of the reducer library.
+ *
+ *              __CILKRTS_STATIC_ASSERT(
+ *                  internal::class_is_empty< internal::binary_functor<Compare> >::value, 
+ *                  "cilk::reducer_max<Value, Compare> only works with an empty Compare class");
+ *
+ *  @note   In a C++11 compiler, this is just the language predefined
+ *          `static_assert` macro.
+ *
+ *  @note   In a non-C++11 compiler, the @a Msg string is not directly included
+ *          in the compiler error message, but it may appear if the compiler
+ *          prints the source line that the error occurred on.
+ *
+ *  @param  Cond    The expression to test.
+ *  @param  Msg     A string explaining the failure.
+ *
+ *  @ingroup common
+ */
+#if defined(__INTEL_CXX11_MODE__) || defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   define  __CILKRTS_STATIC_ASSERT(Cond, Msg) static_assert(Cond, Msg)
+#else
+#   define __CILKRTS_STATIC_ASSERT(Cond, Msg)                               \
+        typedef int __CILKRTS_STATIC_ASSERT_DUMMY_TYPE                      \
+            [::cilk::internal::static_assert_failure<(Cond)>::Success]
+
+/// @cond internal
+    template <bool> struct static_assert_failure { };
+    template <> struct static_assert_failure<true> { enum { Success = 1 }; };
+
+#   define  __CILKRTS_STATIC_ASSERT_DUMMY_TYPE \
+            __CILKRTS_STATIC_ASSERT_DUMMY_TYPE1(__cilkrts_static_assert_, __LINE__)
+#   define  __CILKRTS_STATIC_ASSERT_DUMMY_TYPE1(a, b) \
+            __CILKRTS_STATIC_ASSERT_DUMMY_TYPE2(a, b)
+#   define  __CILKRTS_STATIC_ASSERT_DUMMY_TYPE2(a, b) a ## b
+/// @endcond
+
+#endif
+
+/// @cond internal
+
+/** @name Aligned heap management.
+ */
+//@{
+
+/** Implementation-specific aligned memory allocation function.
+ *
+ *  @param  size        The minimum number of bytes to allocate.
+ *  @param  alignment   The required alignment (must be a power of 2).
+ *  @return             The address of a block of memory of at least @a size
+ *                      bytes. The address will be a multiple of @a alignment.
+ *                      `NULL` if the allocation fails.
+ *
+ *  @see                deallocate_aligned()
+ */
+inline void* allocate_aligned(std::size_t size, std::size_t alignment)
+{
+#ifdef _WIN32
+    return _aligned_malloc(size, alignment);
+#else
+#if defined(ANDROID) || defined(__ANDROID__)
+    return memalign(std::max(alignment, sizeof(void*)), size);
+#else
+    void* ptr;
+    return (posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size) == 0) ? ptr : 0;
+#endif
+#endif        
+}
+
+/** Implementation-specific aligned memory deallocation function.
+ *
+ *  @param  ptr A pointer which was returned by a call to alloc_aligned().
+ */
+inline void deallocate_aligned(void* ptr)
+{
+#ifdef _WIN32
+    _aligned_free(ptr);
+#else
+    std::free(ptr);
+#endif        
+}
+
+/** Class to allocate and guard an aligned pointer.
+ *
+ *  A new_aligned_pointer object allocates aligned heap-allocated memory when
+ *  it is created, and automatically deallocates it when it is destroyed 
+ *  unless its `ok()` function is called.
+ *
+ *  @tparam T   The type of the object to allocate on the heap. The allocated
+ *              will have the size and alignment of an object of type T.
+ */
+template <typename T>
+class new_aligned_pointer {
+    void* m_ptr;
+public:
+    /// Constructor allocates the pointer.
+    new_aligned_pointer() : 
+        m_ptr(allocate_aligned(sizeof(T), internal::align_of<T>::value)) {}
+    /// Destructor deallocates the pointer.
+    ~new_aligned_pointer() { if (m_ptr) deallocate_aligned(m_ptr); }
+    /// Get the pointer.
+    operator void*() { return m_ptr; }
+    /// Return the pointer and release the guard.
+    T* ok() { 
+        T* ptr = static_cast<T*>(m_ptr);
+        m_ptr = 0;
+        return ptr;
+    }
+};
+
+//@}
+
+/// @endcond
+
+} // namespace internal
+
+//@{
+
+/** Allocate an aligned data structure on the heap.
+ *
+ *  `cilk::aligned_new<T>([args])` is equivalent to `new T([args])`, except
+ *  that it guarantees that the returned pointer will be at least as aligned
+ *  as the alignment requirements of type `T`.
+ *
+ *  @ingroup common
+ */
+template <typename T>
+T* aligned_new()
+{
+    internal::new_aligned_pointer<T> ptr;
+    new (ptr) T();
+    return ptr.ok();
+}
+
+template <typename T, typename T1>
+T* aligned_new(const T1& x1)
+{
+    internal::new_aligned_pointer<T> ptr;
+    new (ptr) T(x1);
+    return ptr.ok();
+}
+
+template <typename T, typename T1, typename T2>
+T* aligned_new(const T1& x1, const T2& x2)
+{
+    internal::new_aligned_pointer<T> ptr;
+    new (ptr) T(x1, x2);
+    return ptr.ok();
+}
+
+template <typename T, typename T1, typename T2, typename T3>
+T* aligned_new(const T1& x1, const T2& x2, const T3& x3)
+{
+    internal::new_aligned_pointer<T> ptr;
+    new (ptr) T(x1, x2, x3);
+    return ptr.ok();
+}
+
+template <typename T, typename T1, typename T2, typename T3, typename T4>
+T* aligned_new(const T1& x1, const T2& x2, const T3& x3, const T4& x4)
+{
+    internal::new_aligned_pointer<T> ptr;
+    new (ptr) T(x1, x2, x3, x4);
+    return ptr.ok();
+}
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
+T* aligned_new(const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5)
+{
+    internal::new_aligned_pointer<T> ptr;
+    new (ptr) T(x1, x2, x3, x4, x5);
+    return ptr.ok();
+}
+
+//@}
+
+
+/** Deallocate an aligned data structure on the heap.
+ *
+ *  `cilk::aligned_delete(ptr)` is equivalent to `delete ptr`, except that it
+ *  operates on a pointer that was allocated by aligned_new().
+ *
+ *  @ingroup common
+ */
+template <typename T>
+void aligned_delete(const T* ptr)
+{
+    ptr->~T();
+    internal::deallocate_aligned((void*)ptr);
+}
+
+} // namespace cilk
+
+#endif // __cplusplus
+
+#endif // METAPROGRAMMING_H_INCLUDED
diff --git a/libcilkrts/include/cilk/reducer.h b/libcilkrts/include/cilk/reducer.h
new file mode 100644 (file)
index 0000000..a22651e
--- /dev/null
@@ -0,0 +1,1900 @@
+/*  reducer.h                  -*- C++ -*-
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+/** @file reducer.h
+ *
+ *  @brief Defines foundation classes for creating Cilk reducers.
+ *
+ *  @ingroup Reducers
+ *
+ *  @see @ref pagereducers
+ *
+ *  @defgroup Reducers Reducers
+ */
+#ifndef REDUCER_H_INCLUDED
+#define REDUCER_H_INCLUDED
+
+#include "cilk/hyperobject_base.h"
+#include "cilk/metaprogramming.h"
+
+#ifdef __cplusplus
+
+//===================== C++ interfaces ===================================
+
+#include <new>
+
+namespace cilk {
+
+/** Base class for defining monoids.
+ *
+ *  The monoid_base class template is useful for creating classes that model
+ *  the monoid concept. It provides the core type and memory management
+ *  functionality.  A subclass of monoid_base need only declare and implement
+ *  the `identity` and `reduce` functions. 
+ *
+ *  The monoid_base class also manages the integration between the monoid, the
+ *  reducer class that is based on it, and an optional view class which wraps
+ *  value objects and restricts access to their operations.
+ *
+ *  @tparam Value   The value type for the monoid.
+ *  @tparam View    An optional view class that serves as a proxy for the value
+ *                  type.
+ *
+ *  @see monoid_with_view
+ */
+template <typename Value, typename View = Value>
+class monoid_base
+{
+protected:
+
+    /** Class for provisionally constructed objects.
+     *
+     *  The monoid_base::construct() functions manually construct both a monoid
+     *  and a view. If one of these is constructed successfully, and the
+     *  construction of the other (or some other initialization) fails, then 
+     *  the first one must be destroyed to avoid a memory leak. Because the
+     *  construction is explicit, the destruction must be explicit, too.
+     *
+     *  A provisional_guard object wraps a pointer to a newly constructed
+     *  object. A call to its confirm() function confirms that the object is
+     *  really going to be used. If the guard is destroyed without being
+     *  confirmed, then the pointed-to object is destroyed (but not
+     *  deallocated).
+     *  
+     *  Expected usage:
+     *
+     *      provisional_guard<T1> x1_provisional( new (x1) T1() );
+     *      … more initialization …
+     *      x1_provisional.confirm();
+     *
+     *  or
+     *
+     *      provisional_guard<T1> x1_provisional( new (x1) T1() );
+     *      x1_provisional.confirm_if( new (x2) T2() );
+     *
+     *  If an exception is thrown in the “more initialization” code in the 
+     *  first example, or in the `T2` constructor in the second example, then
+     *  `x1_provisional` will not be confirmed, so when its destructor is 
+     *  called during exception unwinding, the `T1` object that was constructed
+     *  in `x1` will be destroyed.
+     *
+     *  @see provisional()
+     *
+     *  @tparam Type    The type of the provisionally constructed object.
+     */
+    template <typename Type>
+    class provisional_guard {
+        Type* m_ptr;
+    
+    public:
+    
+        /** Constructor. Creates a guard for a provisionally constructed object.
+         *
+         *  @param ptr  A pointer to the provisionally constructed object.
+         */
+        provisional_guard(Type* ptr) : m_ptr(ptr) {}
+        
+        /** Destructor. Destroy the object pointed to by the contained pointer
+         *  if it has not been confirmed.
+         */
+        ~provisional_guard() { if (m_ptr) m_ptr->~Type(); }
+        
+        /** Confirm the provisional construction. Do *not* delete the contained
+         *  pointer when the guard is destroyed.
+         */
+        void confirm() { m_ptr = 0; }
+        
+        /** Confirm provisional construction if argument is non-null. Note that
+         *  if an exception is thrown during evaluation of the argument
+         *  expression, then this function will not be called, and the
+         *  provisional object will not be confirmed. This allows the usage:
+         *
+         *      x1_provisional.confirm_if( new (x2) T2() );
+         *
+         *  @param cond An arbitrary pointer. The provisional object will be
+         *              confirmed if @a cond is not null.
+         * 
+         *  @returns    The value of the @a cond argument.
+         */
+        template <typename Cond>
+        Cond* confirm_if(Cond* cond) { if (cond) m_ptr = 0; return cond; }
+    };
+
+    
+    /** Create a provisional_guard object. This function allows simpler code
+     *  when the only use of a provisional_guard is in a
+     *  provisional_guard::confirm_if() call immediately following its
+     *  creation. Instead of
+     *
+     *      provisional_guard<T>guard( new (ptr_to_T) T() );
+     *      guard.confirm_if( new (ptr_to_U) U() );
+     *
+     *  you can just write
+     *
+     *      provisional( new (ptr_to_T) T() ).confirm_if( new (ptr_to_U) U() );
+     *
+     *  @tparam Type    The type of the provisionally constructed object.
+     *
+     *  @param  ptr     A pointer to a provisionally constructed object.
+     *
+     *  @returns        A @ref provisional_guard object that guards the
+     *                  provisionally constructed object pointed to by @a ptr.
+     */
+    template <typename Type> 
+    static provisional_guard<Type> provisional(Type* ptr) 
+        { return provisional_guard<Type>(ptr); }
+
+public:
+
+    /** Value type of the monoid.
+     */
+    typedef Value   value_type;
+    
+    /** View type of the monoid. Defaults to be the same as the value type.
+     *  @see monoid_with_view
+     */
+    typedef View    view_type;
+    
+    enum { 
+        /** Should reducers created with this monoid be aligned?
+         *
+         *  @details
+         *  “Aligned” means that the view is allocated at a cache-line aligned
+         *  offset in the reducer, and the reducer must be cache-line aligned.
+         *  “Unaligned” means that the reducer as a whole is just naturally 
+         *  aligned, but it contains a large enough block of uninitialized 
+         *  storage for a cache-line aligned view to be allocated in it at
+         *  reducer construction time.
+         *
+         *  Since the standard heap allocator (new reducer) does not allocate 
+         *  cache-line aligned storage, only unaligned reducers can be safely
+         *  allocated on the heap.
+         *  
+         *  Default is false (unaligned) unless overridden in a subclass.
+         *
+         *  @since 1.02
+         *  (In Cilk library versions 1.0 and 1.01, the default was true.
+         *  In Cilk library versions prior to 1.0, reducers were always aligned,
+         *  and this data member did not exist.)
+         */
+        align_reducer = false 
+    };
+    
+    /** Destroy a view. Destroys (without deallocating) the @a View object
+     *  pointed to by @a p.
+     *
+     *  @param p    The address of the @a View object to be destroyed.
+     */
+    void destroy(view_type* p) const { p->~view_type(); }
+
+    /** Allocate raw memory. Allocate @a s bytes of memory with no
+     *  initialization.
+     *
+     *  @param s    The number of bytes of memory to allocate.
+     *  @return     An untyped pointer to the allocated memory.
+     */
+    void* allocate(size_t s) const { return operator new(s); }
+
+    /** Deallocate raw memory. Deallocates the memory pointed to by @a p 
+     *  without doing any destruction.
+     *
+     *  @param p    Pointer to the memory to be deallocated.
+     *
+     *  @pre        @a p points to a block of memory that was allocated by a
+     *              call to allocate().
+     */
+    void deallocate(void* p) const { operator delete(p); }
+
+    /** Create the identity value. Constructs (without allocating) a @a View
+     *  object representing the default value of the @a Value type.
+     *
+     *  @param p    A pointer to a block of raw memory large enough to hold a 
+     *              @a View object.
+     *
+     *  @post       The memory pointed to by @a p contains a @a View object that
+     *              represents the default value of the @a View type.
+     *
+     *  @deprecated This function constructs the @a View object with its default
+     *              constructor, which will often, but not always, yield the
+     *              appropriate identity value. Monoid classes should declare
+     *              their identity function explicitly, rather than relying on
+     *              this default definition.
+     */
+    void identity(View* p) const { new ((void*) p) View(); }
+    
+    
+    /** @name Construct the monoid and the view with arbitrary arguments.
+     *
+     *  A @ref reducer object contains monoid and view data members, which are
+     *  declared as raw storage (byte arrays), so that they are not implicitly
+     *  constructed when the reducer is constructed. Instead, a reducer
+     *  constructor calls one of the monoid class’s static construct() 
+     *  functions with the addresses of the monoid and the view, and the
+     *  construct() function uses placement `new` to construct them.
+     *
+     *  This allows the monoid to determine the order in which the monoid and
+     *  view are constructed, and to make one of them dependent on the other.
+     *
+     *  Any arguments to the reducer constructor are just passed on as 
+     *  additional arguments to the construct() function (after the monoid
+     *  and view addresses).
+     *
+     *  Any monoid whose needs are satisfied by the suite of construct() 
+     *  functions below, such as @ref monoid_with_view, can just inherit them
+     *  from monoid_base. Other monoids will need to provide their own versions
+     *  to override the monoid_base functions.
+     */
+    //@{
+    
+    /** Default-construct the monoid, and pass zero to five const reference
+     *  arguments to the view constructor.
+     */
+    //@{
+    
+    template <typename Monoid>
+    static void construct(Monoid* monoid, View* view)
+        { provisional( new ((void*)monoid) Monoid() ).confirm_if( 
+            (monoid->identity(view), view) ); }
+
+    template <typename Monoid, typename T1>
+    static void construct(Monoid* monoid, View* view, const T1& x1)
+        { provisional( new ((void*)monoid) Monoid() ).confirm_if( 
+            new ((void*)view) View(x1) ); }
+
+    template <typename Monoid, typename T1, typename T2>
+    static void construct(Monoid* monoid, View* view, 
+                            const T1& x1, const T2& x2)
+        { provisional( new ((void*)monoid) Monoid() ).confirm_if( 
+            new ((void*)view) View(x1, x2) ); }
+
+    template <typename Monoid, typename T1, typename T2, typename T3>
+    static void construct(Monoid* monoid, View* view, 
+                            const T1& x1, const T2& x2, const T3& x3)
+        { provisional( new ((void*)monoid) Monoid() ).confirm_if( 
+            new ((void*)view) View(x1, x2, x3) ); }
+
+    template <typename Monoid, typename T1, typename T2, typename T3, 
+                typename T4>
+    static void construct(Monoid* monoid, View* view, 
+                            const T1& x1, const T2& x2, const T3& x3, 
+                            const T4& x4)
+        { provisional( new ((void*)monoid) Monoid() ).confirm_if( 
+            new ((void*)view) View(x1, x2, x3, x4) ); }
+
+    template <typename Monoid, typename T1, typename T2, typename T3, 
+                typename T4, typename T5>
+    static void construct(Monoid* monoid, View* view, 
+                            const T1& x1, const T2& x2, const T3& x3, 
+                            const T4& x4, const T5& x5)
+        { provisional( new ((void*)monoid) Monoid() ).confirm_if( 
+            new ((void*)view) View(x1, x2, x3, x4, x5) ); }
+        
+    //@}
+    
+    /** Default-construct the monoid, and pass one non-const reference argument
+     *  to the view constructor.
+     */
+    //@{
+    template <typename Monoid, typename T1>
+    static void construct(Monoid* monoid, View* view, T1& x1)
+        { provisional( new ((void*)monoid) Monoid() ).confirm_if( 
+            new ((void*)view) View(x1) ); }
+    //@}
+
+    /** Copy-construct the monoid, and pass zero to four const reference
+     *  arguments to the view constructor.
+     */
+    //@{
+
+    template <typename Monoid>
+    static void construct(Monoid* monoid, View* view, const Monoid& m)
+        { provisional( new ((void*)monoid) Monoid(m) ).confirm_if( 
+            new ((void*)view) View() ); }
+
+    template <typename Monoid, typename T1>
+    static void construct(Monoid* monoid, View* view, const Monoid& m, 
+                            const T1& x1)
+        { provisional( new ((void*)monoid) Monoid(m) ).confirm_if( 
+            new ((void*)view) View(x1) ); }
+        
+    template <typename Monoid, typename T1, typename T2>
+    static void construct(Monoid* monoid, View* view, const Monoid& m, 
+                            const T1& x1, const T2& x2)
+    { provisional( new ((void*)monoid) Monoid(m) ).confirm_if( 
+        new ((void*)view) View(x1, x2) ); }
+        
+    template <typename Monoid, typename T1, typename T2, typename T3>
+    static void construct(Monoid* monoid, View* view, const Monoid& m, 
+                            const T1& x1, const T2& x2, const T3& x3)
+    {
+        provisional( new ((void*)monoid) Monoid(m) ).confirm_if(
+            new ((void*)view) View(x1, x2, x3) );
+    }
+        
+    template <typename Monoid, typename T1, typename T2, typename T3, 
+                typename T4>
+    static void construct(Monoid* monoid, View* view, const Monoid& m, 
+                            const T1& x1, const T2& x2, const T3& x3, 
+                            const T4& x4)
+    {
+        provisional( new ((void*)monoid) Monoid(m) ).confirm_if(
+            new ((void*)view) View(x1, x2, x3, x4) );
+    }
+        
+    //@}
+    
+    //@}
+};
+
+
+/** Monoid class that gets its value type and identity and reduce operations
+ *  from its view.
+ *
+ *  A simple implementation of the monoid-view-reducer architecture would
+ *  distribute knowledge about the type and operations for the reduction 
+ *  between the monoid and the view — the identity and reduction operations are
+ *  specified in the monoid, the reduction operations are implemented in the
+ *  view, and the value type is specified in both the monoid and the view.
+ *  This is inelegant.
+ *
+ *  monoid_with_view is a subclass of @ref monoid_base that gets its value type
+ *  and its identity and reduction operations from its view class. No
+ *  customization of the monoid_with_view class itself is needed beyond
+ *  instantiating it with an appropriate view class. (Customized subclasses of
+ *  monoid_with_view may be needed for other reasons, such as to keep some
+ *   state for the reducer.) All of the Cilk predefined reducers use
+ *  monoid_with_view or one of its subclasses.
+ *  
+ *  The view class `View` of a monoid_with_view must provide the following public definitions:
+ *
+ *  Definition                       | Meaning
+ *  ---------------------------------|--------
+ *  `value_type`                     | a typedef of the value type for the reduction
+ *  `View()`                         | a default constructor which constructs the identity value for the reduction
+ *  `void reduce(const View* other)` | a member function which applies the reduction operation to the values of `this` view and the `other` view, leaving the result as the value of `this` view, and leaving the value of the `other` view undefined (but valid)
+ *
+ *  @tparam View    The view class for the monoid.
+ *  @tparam Align   If true, reducers instantiated on this monoid will be
+ *                  cache-aligned. By default, library reducers (unlike legacy
+ *                  library reducer _wrappers_) are aligned only as required by
+ *                  contents.
+ */
+template <class View, bool Align = false>
+class monoid_with_view : public monoid_base<typename View::value_type, View>
+{
+public:
+    /** Should reducers created with this monoid be aligned?
+     */
+    enum { align_reducer = Align };
+    
+    /** Create the identity value.
+     *
+     *  Implements the monoid `identity` operation by using the @a View class’s
+     *  default constructor.
+     *
+     *  @param  p   A pointer to a block of raw memory large enough to hold a 
+     *              @p View object.
+     */
+    void identity(View* p) const { new ((void*)p) View(); }
+    
+    /** Reduce the values of two views.
+     *
+     *  Implements the monoid `reduce` operation by calling the left view’s
+     *  `%reduce()` function with the right view as an operand.
+     *
+     *  @param  left    The left operand of the reduce operation.
+     *  @param  right   The right operand of the reduce operation.
+     *  @post           The left view contains the result of the reduce
+     *                  operation, and the right view is undefined.
+     */
+    void reduce(View* left, View* right) const { left->reduce(right); }
+};
+
+
+/** Base class for simple views with (usually) scalar values.
+ *
+ *  The scalar_view class is intended as a base class which provides about half
+ *  of the required definitions for simple views. It defines the `value_type`
+ *  required by a @ref monoid_with_view (but not the identity constructor and
+ *  reduce operation, which are inherently specific to a particular kind of
+ *  reduction). It also defines the value access functions which will be called
+ *  by the corresponding @ref reducer functions. (It uses copy semantics for 
+ *  the view_move_in() and view_move_out() functions, which is appropriate
+ *  for simple scalar types, but not necessarily for more complex types like
+ *  STL containers.
+ *
+ *  @tparam Type    The type of value wrapped by the view.
+ */
+template <typename Type>
+class scalar_view
+{
+protected:
+    Type m_value;       ///< The wrapped accumulator variable.
+
+public:
+    /** Value type definition required by @ref monoid_with_view.
+     */
+    typedef Type value_type;
+    
+    /** Default constructor.
+     */
+    scalar_view() : m_value() {}    
+    
+    /** Value constructor.
+     */
+    scalar_view(const Type& v) : m_value(v) {}
+    
+    /** @name Value functions required by the reducer class.
+     *
+     *  Note that the move in/out functions use simple assignment semantics.
+     */
+    //@{
+
+    /** Set the value of the view.
+     */
+    void view_move_in(Type& v) { m_value = v; }
+
+    /** Get the value of the view.
+     */
+    void view_move_out(Type& v) { v = m_value; }
+
+    /** Set the value of the view.
+     */
+    void view_set_value(const Type& v) { m_value = v; }
+
+    /** Get the value of the view.
+     */
+    Type const& view_get_value() const { return m_value; }
+    
+    /** Get a reference to the value contained in the view. For legacy
+     *  reducer support only.
+     */
+    Type      & view_get_reference()       { return m_value; }
+    
+    /** Get a reference to the value contained in the view. For legacy
+     *  reducer support only.
+     */
+    Type const& view_get_reference() const { return m_value; }
+    //@}
+};
+
+
+/** Wrapper class for move-in construction.
+ *
+ *  Some types allow their values to be _moved_ as an alternative to copying.
+ *  Moving a value may be much faster than copying it, but may leave the value
+ *  of the move’s source undefined. Consider the `swap` operation provided by
+ *  many STL container classes:
+ *
+ *      list<T> x, y;
+ *      x = y;      // Copy
+ *      x.swap(y);  // Move
+ *
+ *  The assignment _copies_ the value of `y` into `x` in time linear in the 
+ *  size of `y`, leaving `y` unchanged. The `swap` _moves_ the  value of `y`
+ *  into `x` in constant time, but it also moves the value of `x` into `y`,
+ *  potentially leaving `y` undefined.
+ *  
+ *  A move_in_wrapper simply wraps a pointer to an object. It is created by a
+ *  call to cilk::move_in(). Passing a move_in_wrapper to a view constructor
+ *  (actually, passing it to a reducer constructor, which passes it to the
+ *  monoid `construct()` function, which passes it to the view constructor)
+ *  allows, but does not require, the value pointed to by the wrapper to be
+ *  moved into the view instead of copied.
+ *
+ *  A view class exercises this option by defining a _move-in constructor_,
+ *  i.e., a constructor with a move_in_wrapper parameter. The constructor calls
+ *  the wrapper’s `value()` function to get a reference to its pointed-to 
+ *  value, and can then use that reference in a move operation.
+ *
+ *  A move_in_wrapper also has an implicit conversion to its pointed-to value,
+ *  so if a view class does not define a move-in constructor, its ordinary 
+ *  value constructor will be called with the wrapped value. For example, an
+ *  @ref ReducersAdd "op_add" view does not have a move-in constructor, so
+ *
+ *      int x;
+ *      reducer< op_add<int> > xr(move_in(x));
+ *
+ *  will simply call the `op_add_view(const int &)` constructor. But an 
+ *  @ref ReducersList "op_list_append" view does have a move-in  constructor,
+ *  so
+ *
+ *      list<int> x;
+ *      reducer< op_list_append<int> > xr(move_in(x));
+ *
+ *  will call the `op_list_append_view(move_in_wrapper<int>)` constructor,
+ *  which can `swap` the value of `x` into the view.
+ *
+ *  @note   Remember that passing the value of a variable to a reducer
+ *          constructor using a move_in_wrapper leaves the variable undefined.
+ *          You cannot assume that the constructor either will or will not copy
+ *          or move the value.
+ *
+ *  @tparam Type    The type of the wrapped value.
+ *
+ *  @see cilk::move_in()
+ */
+template <typename Type>
+class move_in_wrapper
+{
+    Type *m_pointer;
+public:
+    
+    /** Constructor that captures the address of its argument. This is almost
+     *  always called from the @ref move_in function.
+     */
+    explicit move_in_wrapper(Type& ref) : m_pointer(&ref) { }
+    
+    /** Implicit conversion to the wrapped value. This allows a move_in_wrapper
+     *  to be used where a value of the wrapped type is expected, in which case
+     *  the wrapper is completely transparent.
+     */
+    operator Type&() const { return *m_pointer; }
+    
+    /** Get a reference to the pointed-to value. This has the same effect as 
+     *  the implicit conversion, but makes the intent clearer in a move-in
+     *  constructor.
+     */
+    Type& value() const { return *m_pointer; }
+};
+
+/** Function to create a move_in_wrapper for a value.
+ *
+ *  @tparam Type    The type of the argument, which will be the `type` of the 
+ *                  created wrapper.
+ *
+ *  @see move_in_wrapper
+ */
+template <typename Type>
+inline
+move_in_wrapper<Type> move_in(Type& ref)
+    { return move_in_wrapper<Type>(ref); }
+
+
+/** @copydoc move_in(Type&)
+ *
+ *  @note   Applying a function that is explicitly specified as modifying its
+ *          argument to a const argument is obviously an irrational thing to 
+ *          do. This move_in() variant is just provided to allow calling a
+ *          move-in constructor with a function return value, which the 
+ *          language treats as a const. Using it for any other purpose will
+ *          probably end in tears.
+ */
+template <typename Type>
+inline
+move_in_wrapper<Type> move_in(const Type& ref)
+    { return move_in_wrapper<Type>(ref); }
+
+
+/** Wrapper class to allow implicit downcasts to reducer subclasses.
+ *
+ *  The Cilk library contains a collection of reducer wrapper classes which 
+ *  were created before the `cilk::reducer<Monoid>` style was developed. For 
+ *  example, `cilk::reducer_opadd<Type>` provided essentially the same
+ *  functionality that is now provided by 
+ *  `cilk::reducer< cilk::op_add<Type> >`. These legacy reducer classes are 
+ *  deprecated, but still supported, and they have been reimplemented as 
+ *  subclasses of the corresponding `cilk::reducer` classes. For example:
+ *
+ *      template <class T>
+ *      reducer_opadd<T> : public reducer< op_add<T> > { ... };
+ *
+ *  This reimplementation allows transparent conversion between legacy and 
+ *  new reducers. That is, a `reducer<op_add>*` or `reducer<op_add>&` can be 
+ *  used anywhere that a `reducer_opadd*` or `reducer_opadd&` is expected, 
+ *  and vice versa. 
+ *
+ *  The conversion from the legacy reducer to the new reducer is just an 
+ *  up-cast, which is provided for free by C++. The conversion from the new 
+ *  reducer to the legacy reducer is a down-cast, though, which requires an 
+ *  explicit conversion member function in the `reducer` class. The challenge
+ *  is to define a function in the reducer template class which will convert
+ *  each cilk::reducer specialization to the corresponding legacy reducer, 
+ *  if there is one.
+ *
+ *  The trick is in the legacy_reducer_downcast template class, which provides
+ *  a mapping from  `cilk::reducer` specializations to legacy reducer classes.
+ *  `reducer<Monoid>` has a conversion function to convert itself to 
+ *  `legacy_reducer_downcast< reducer<Monoid> >::%type`. By default,
+ *  `legacy_reducer_downcast<Reducer>::%type` is just a trivial subclass of
+ *  `Reducer`, which is uninteresting, but a reducer with a legacy counterpart
+ *  will have a specialization of `legacy_reducer_downcast` whose `type` is 
+ *  the corresponding legacy reducer. For example:
+ *
+ *      template <typename Type>
+ *      struct legacy_reducer_downcast< reducer< op_add<Type> > >
+ *      {
+ *          typedef reducer_opadd<Type> type;
+ *      };
+ *
+ *
+ *  @tparam Reducer The new-style reducer class whose corresponding legacy reducer class
+ *                  is `type`, if there is such a legacy reducer class.
+ */
+template <typename Reducer>
+struct legacy_reducer_downcast
+{
+    /** The related legacy reducer class.
+     *
+     *  By default, this is just a trivial subclass of Reducer, but it can be 
+     *  overridden in the specialization of legacy_reducer_downcast for 
+     *  a reducer that has a corresponding legacy reducers.
+     */
+    struct type : Reducer { };
+};
+
+
+namespace internal {
+/// @cond internal
+
+template <typename Value, typename View>
+struct reducer_set_get
+{
+    static View theView;  // Declared but not defined
+
+    // sizeof(notchar) is guaranteed larger than 1
+    struct notchar { char x[2]; };
+
+    // check_for_ref returns char if 'get_value' returns by value and notchar
+    // if 'get_value' returns by reference.
+    static char    check_for_ref(Value,  ...);
+    static notchar check_for_ref(Value&, int);
+
+    enum { GET_VALUE_BY_VALUE =
+           (1 == sizeof(check_for_ref(theView.view_get_value(), 0))) } ;
+
+    typedef typename condition<GET_VALUE_BY_VALUE,
+                               Value, const Value&>::type get_value_type;
+
+    static void move_in(View& view, Value& v)   { view.view_move_in(v); }
+    static void move_out(View& view,  Value& v) { view.view_move_out(v); }
+
+    static void set_value(View& view, const Value& v)
+        { view.view_set_value(v); }
+
+    static get_value_type get_value(const View& view)
+        { return view.view_get_value(); }
+};
+
+template <typename Value>
+struct reducer_set_get<Value, Value>
+{
+    typedef const Value& get_value_type;
+
+    static void move_in(Value& view, Value& v)   { view = v; }
+    static void move_out(Value& view,  Value& v) { v = view; }
+
+    static void set_value(Value& view, const Value& v) { view = v; }
+
+    static get_value_type get_value(const Value& view) { return view; }
+};
+
+/// @endcond
+
+
+/** Base class defining the data layout that is common to all reducers.
+ */
+template <typename Monoid> 
+class reducer_base {
+    typedef typename Monoid::view_type view_type;
+
+    // This makes the reducer a hyper-object. (Partially initialized in
+    // the derived reducer_content class.)
+    //
+    __cilkrts_hyperobject_base      m_base;
+
+    // The monoid is allocated here as raw bytes, and is constructed explicitly
+    // by a call to the monoid_type::construct() function in the constructor of
+    // the `reducer` subclass.
+    //
+    storage_for_object<Monoid>      m_monoid;
+
+    // Used for sanity checking at destruction.
+    //
+    void*                           m_initialThis;
+    
+    // The leftmost view comes next. It is defined in the derived
+    // reducer_content class.
+    
+    /** @name C-callable wrappers for the C++-coded monoid dispatch functions.
+     */
+    //@{
+    
+    static void reduce_wrapper(void* r, void* lhs, void* rhs);
+    static void identity_wrapper(void* r, void* view);
+    static void destroy_wrapper(void* r, void* view);
+    static void* allocate_wrapper(void* r, __STDNS size_t bytes);
+    static void deallocate_wrapper(void* r, void* view);
+    
+    //@}
+
+protected:
+
+    /** Constructor.
+     *
+     *  @param  leftmost    The address of the leftmost view in the reducer.
+     */
+    reducer_base(char* leftmost) 
+    {
+        static const cilk_c_monoid c_monoid_initializer = {
+            (cilk_c_reducer_reduce_fn_t)     &reduce_wrapper,
+            (cilk_c_reducer_identity_fn_t)   &identity_wrapper,
+            (cilk_c_reducer_destroy_fn_t)    &destroy_wrapper,
+            (cilk_c_reducer_allocate_fn_t)   &allocate_wrapper,
+            (cilk_c_reducer_deallocate_fn_t) &deallocate_wrapper
+        };
+
+        m_base.__c_monoid = c_monoid_initializer;
+        m_base.__flags = 0;
+        m_base.__view_offset = (char*)leftmost - (char*)this;
+        m_base.__view_size = sizeof(view_type);
+        m_initialThis = this;
+        
+        __cilkrts_hyper_create(&m_base);
+    }
+    
+    /** Destructor.
+     */
+    __CILKRTS_STRAND_STALE(~reducer_base())
+    {
+        // Make sure we haven't been memcopy'd or corrupted
+        __CILKRTS_ASSERT(
+            this == m_initialThis ||
+            // Allow for a layout bug that may put the initialThis field one 
+            // word later in 1.0 reducers than in 0.9  and 1.1 reducers.
+            this == *(&m_initialThis + 1)
+        );
+        __cilkrts_hyper_destroy(&m_base);
+    }
+
+    /** Monoid data member.
+     *
+     *  @return A pointer to the reducer’s monoid data member.
+     */
+    Monoid* monoid_ptr() { return &m_monoid.object(); }
+
+    /** Leftmost view data member.
+     *
+     *  @return A pointer to the reducer’s leftmost view data member.
+     *
+     *  @note   This function returns the address of the *leftmost* view, 
+     *          which is unique for the lifetime of the reducer. It is 
+     *          intended to be used in constructors and destructors. 
+     *          Use the reducer::view() function to access the per-strand 
+     *          view instance.
+     */
+    view_type* leftmost_ptr() 
+    {
+        char* view_addr = (char*)this + m_base.__view_offset;
+        return reinterpret_cast<view_type*>(view_addr);
+    }
+    
+public:
+
+    /** @name Access the current view.
+     *
+     *  These functions return a reference to the instance of the reducer’s 
+     *  view that was created for the current strand of a parallel computation
+     *  (and create it if it doesn’t already exist). Note the difference from
+     *  the (private) leftmost_ptr() function, which returns a pointer to the
+     *  _leftmost_ view, which is the same in all strands.
+     */
+    //@{
+    
+    /** Per-strand view instance.
+     *
+     *  @return A reference to the per-strand view instance.
+     */
+    view_type& view() 
+    {
+        return *static_cast<view_type *>(__cilkrts_hyper_lookup(&m_base)); 
+    }
+    
+    /** @copydoc view()
+     */
+    const view_type& view() const 
+    { 
+        return const_cast<reducer_base*>(this)->view(); 
+    }
+    
+    //@}
+    
+    /** Initial view pointer field.
+     *
+     *  @internal
+     *
+     *  @return a reference to the m_initialThis field.
+     *
+     *  @note   This function is provided for “white-box” testing of the
+     *          reducer layout code. There is never any reason for user code
+     *          to call it.
+     */
+    const void* const & initial_this() const { return m_initialThis; }
+};
+
+template <typename Monoid>
+void reducer_base<Monoid>::reduce_wrapper(void* r, void* lhs, void* rhs)
+{
+    Monoid* monoid = static_cast<reducer_base*>(r)->monoid_ptr();
+    monoid->reduce(static_cast<view_type*>(lhs),
+                         static_cast<view_type*>(rhs));
+}
+
+template <typename Monoid>
+void reducer_base<Monoid>::identity_wrapper(void* r, void* view)
+{
+    Monoid* monoid = static_cast<reducer_base*>(r)->monoid_ptr();
+    monoid->identity(static_cast<view_type*>(view));
+}
+
+template <typename Monoid>
+void reducer_base<Monoid>::destroy_wrapper(void* r, void* view)
+{
+    Monoid* monoid = static_cast<reducer_base*>(r)->monoid_ptr();
+    monoid->destroy(static_cast<view_type*>(view));
+}
+
+template <typename Monoid>
+void* reducer_base<Monoid>::allocate_wrapper(void* r, __STDNS size_t bytes)
+{
+    Monoid* monoid = static_cast<reducer_base*>(r)->monoid_ptr();
+    return monoid->allocate(bytes);
+}
+
+template <typename Monoid>
+void reducer_base<Monoid>::deallocate_wrapper(void* r, void* view)
+{
+    Monoid* monoid = static_cast<reducer_base*>(r)->monoid_ptr();
+    monoid->deallocate(static_cast<view_type*>(view));
+}
+
+
+/** Base class defining the data members of a reducer.
+ *
+ *  @tparam Aligned The `m_view` data member, and therefore the entire 
+ *                  structure, are cache-line aligned if this parameter
+ *                  is `true'.
+ */
+template <typename Monoid, bool Aligned = Monoid::align_reducer>
+class reducer_content;
+
+/** Base class defining the data members of an aligned reducer.
+ */
+template <typename Monoid>
+class reducer_content<Monoid, true> : public reducer_base<Monoid>
+{
+    typedef typename Monoid::view_type view_type;
+    
+    // The leftmost view is defined as raw bytes. It will be constructed
+    // by the monoid `construct` function. It is cache-aligned, which 
+    // will push it into a new cache line. Furthermore, its alignment causes
+    // the reducer as a whole to be cache-aligned, which makes the reducer 
+    // size a multiple of a cache line. Since there is nothing in the reducer 
+    // after the view, all this means that the leftmost view gets one or more
+    // cache lines all to itself, which prevents false sharing.
+    //
+    __CILKRTS_CACHE_ALIGN
+    char m_leftmost[sizeof(view_type)];
+
+    /** Test if the reducer is cache-line-aligned.
+     *
+     *  Used in assertions.
+     */
+    bool reducer_is_cache_aligned() const
+        { return 0 == ((std::size_t) this & (__CILKRTS_CACHE_LINE__ - 1)); }
+        
+protected:
+
+    /** Constructor.
+     */
+    reducer_content() : reducer_base<Monoid>((char*)&m_leftmost)
+    {
+#ifndef CILK_IGNORE_REDUCER_ALIGNMENT
+    assert(reducer_is_cache_aligned() &&
+           "Reducer should be cache aligned. Please see comments following this assertion for explanation and fixes.");
+#endif
+    /*  "REDUCER SHOULD BE CACHE ALIGNED" ASSERTION.
+     *
+     *  This Reducer class instantiation specifies cache-line alignment of the 
+     *  leftmost view field (and, implicitly, of the reducer itself). You got
+     *  this assertion because a reducer with this class was allocated at a
+     *  non-cache-aligned address, probably because it was allocated on the 
+     *  heap with `new`. This can be a problem for two reasons:
+     *
+     *  1.  If the leftmost view is not on a cache line by itself, there might
+     *      be a slowdown resulting from accesses to the same cache line from
+     *      different threads.
+     *
+     *  2.  The compiler thinks that reducer is cache-line aligned, but it
+     *      really isn't. If the reducer is contained in a structure, then the
+     *      compiler will believe that the containing structure, and other
+     *      fields contained in it, are also more aligned than they really
+     *      are. In particular, if the structure contains a numeric array that
+     *      is used in a vectorizable loop, then the compiler might generate
+     *      invalid vector instructions, resulting in a runtime error.
+     *
+     *  The compiler will always allocate reducer variables, and structure
+     *  variables containing reducers, with their required alignment.
+     *  Reducers, and structures containing a reducer, which are allocated
+     *  on the heap with `new` will _not_ be properly aligned.
+     *
+     *  There are three ways that you can fix this assertion failure.
+     *
+     *  A.  Rewrite your code to use the new-style `reducer< op_XXX<Type> >` 
+     *      instead of the legacy `reducer_XXX<type>`. The new-style reducers
+     *      are not declared to be cache-aligned, and will work properly if
+     *      they are not cache-aligned.
+     *
+     *  B.  If you must allocate an old-style reducer or a structure containing
+     *      a reducer on the heap, figure out how to align it correctly. The
+     *      suggested fix is to use `cilk::aligned_new()` and 
+     *      `cilk::aligned_delete()` instead of `new` and `delete`, as follows:
+     *
+     *          Type* ptr = cilk::aligned_new<Type>(constructor-arguments);
+     *          cilk::aligned_delete(ptr);
+     *
+     *  C.  Define the macro CILK_IGNORE_REDUCER_ALIGNMENT, which will suppress
+     *      the assertion check. Do this only if you are comfortable that
+     *      problem (2) above will not occur.
+     */
+    }
+};
+
+/** Base class defining the data members of an unaligned reducer.
+ */
+template <typename Monoid>
+class reducer_content<Monoid, false> : public reducer_base<Monoid>
+{
+    typedef typename Monoid::view_type view_type;      ///< The view type.
+
+    // Reserve space for the leftmost view. The view will be allocated at an
+    // aligned offset in this space at runtime, to guarantee that the view
+    // will get one or more cache lines all to itself, to prevent false 
+    // sharing.
+    //
+    // The number of bytes to reserve is determined as follows:
+    // * Start with the view size.
+    // * Round up to a multiple of the cache line size, to get the total size
+    //   of the cache lines that will be dedicated to the view.
+    // * Add (cache line size - 1) filler bytes to guarantee that the reserved
+    //   area will contain a cache-aligned block of the required cache lines,
+    //   no matter where the reserved area starts.
+    //
+    char m_leftmost[
+        // View size rounded up to multiple cache lines
+        (   (sizeof(view_type) + __CILKRTS_CACHE_LINE__ - 1)
+            & ~ (__CILKRTS_CACHE_LINE__ - 1)
+        )
+        // plus filler to allow alignment.
+        + __CILKRTS_CACHE_LINE__ - 1
+        ];
+
+protected:
+
+    /** Constructor. Find the first cache-aligned position in the reserved
+     *  area, and pass it to the base constructor as the leftmost view 
+     *  address.
+     */
+    reducer_content() : 
+        reducer_base<Monoid>(
+            (char*)( ((std::size_t)&m_leftmost + __CILKRTS_CACHE_LINE__ - 1)
+                     & ~ (__CILKRTS_CACHE_LINE__ - 1) ) )
+    {}
+};
+
+
+} // namespace internal
+
+
+// The __cilkrts_hyperobject_ functions are defined differently depending on
+// whether a file is compiled with or without the CILK_STUB option. Therefore,
+// reducers compiled in the two modes should be link-time incompatible, so that
+// object files compiled with stubbed reducers won't be linked into an
+// unstubbed program, or vice versa. We achieve this by putting the reducer
+// class definition into the cilk::stub namespace in a stubbed compilation.
+
+#ifdef CILK_STUB
+namespace stub {
+#endif
+
+/** Reducer class.
+ *
+ *  A reducer is instantiated on a Monoid.  The Monoid provides the value
+ *  type, associative reduce function, and identity for the reducer.
+ *
+ *  @tparam Monoid  The monoid class that the reducer is instantiated on. It must model
+ *                  the @ref reducers_monoid_concept "monoid concept".
+ *
+ *  @see @ref pagereducers
+ */
+template <class Monoid>
+class reducer : public internal::reducer_content<Monoid>
+{
+    typedef internal::reducer_content<Monoid> base;
+    using base::monoid_ptr;
+    using base::leftmost_ptr;
+  public:
+    typedef Monoid                          monoid_type;    ///< The monoid type.
+    typedef typename Monoid::value_type     value_type;     ///< The value type.
+    typedef typename Monoid::view_type      view_type;      ///< The view type.
+
+  private:
+    typedef internal::reducer_set_get<value_type, view_type> set_get;
+    
+    reducer(const reducer&);                ///< Disallow copying.
+    reducer& operator=(const reducer&);     ///< Disallow assignment.
+
+  public:
+  
+    /** @name Constructors
+     *
+     *  All reducer constructors call the static `construct()` function of the monoid class to
+     *  construct the reducer's monoid and leftmost view. 
+     *
+     *  The reducer constructor arguments are simply passed through to the construct() function.
+     *  Thus, the constructor parameters accepted by a particular reducer class are determined
+     *  by its monoid class.
+     */
+    //@{
+
+    /** 0 – 6 const reference parameters.
+     */
+    //@{
+    
+    reducer()
+    {
+        monoid_type::construct(monoid_ptr(), leftmost_ptr());
+    }
+
+    template <typename T1>
+    reducer(const T1& x1)
+    {
+        monoid_type::construct(monoid_ptr(), leftmost_ptr(), x1);
+    }
+
+    template <typename T1, typename T2>
+    reducer(const T1& x1, const T2& x2)
+    {
+        monoid_type::construct(monoid_ptr(), leftmost_ptr(), x1, x2);
+    }
+
+    template <typename T1, typename T2, typename T3>
+    reducer(const T1& x1, const T2& x2, const T3& x3)
+    {
+        monoid_type::construct(monoid_ptr(), leftmost_ptr(), x1, x2, x3);
+    }
+
+    template <typename T1, typename T2, typename T3, typename T4>
+    reducer(const T1& x1, const T2& x2, const T3& x3, const T4& x4)
+    {
+        monoid_type::construct(monoid_ptr(), leftmost_ptr(), x1, x2, x3, x4);
+    }
+
+    template <typename T1, typename T2, typename T3, typename T4, typename T5>
+    reducer(const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5)
+    {
+        monoid_type::construct(monoid_ptr(), leftmost_ptr(), x1, x2, x3, x4, x5);
+    }
+
+    template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+    reducer(const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5, const T6& x6)
+    {
+        monoid_type::construct(monoid_ptr(), leftmost_ptr(), x1, x2, x3, x4, x5, x6);
+    }
+    
+    //@}
+    
+    /** 1 non-const reference parameter.
+     */
+    //@{
+
+    template <typename T1>
+    reducer(T1& x1)
+    {
+        monoid_type::construct(monoid_ptr(), leftmost_ptr(), x1);
+    }
+    
+    //@}
+
+    /** Destructor.
+     */
+    __CILKRTS_STRAND_STALE(~reducer())
+    {
+        leftmost_ptr()->~view_type();
+        monoid_ptr()->~monoid_type();
+    }
+
+    //@{
+    /** Get the monoid.
+     *
+     *  @return A reference to the monoid object belonging to this reducer.
+     */
+    Monoid& monoid() { return *monoid_ptr(); }
+    
+    const Monoid& monoid() const 
+    { return const_cast<reducer*>(this)->monoid(); }
+    //@}
+
+    //@{
+    /** Access the current view.
+     *
+     *  Return a reference to the instance of the reducer’s view that was 
+     *  created for the current strand of a parallel computation (and create
+     *  it if it doesn’t already exist).
+     */
+          view_type& view()       { return base::view(); }
+    const view_type& view() const { return base::view(); }
+    //@}
+        
+
+    /** @name Dereference the reducer to get the view.
+     *
+     *  “Dereferencing” a reducer yields the view for the current strand. The
+     *  view, in turn, acts as a proxy for its contained value, exposing only
+     *  those operations which are consistent with the reducer’s monoid. Thus,
+     *  all modifications of the reducer’s accumulator variable are written as
+     *
+     *      *reducer OP ...
+     *
+     *  or
+     *
+     *      reducer->func(...)
+     *
+     *  (The permitted operations on a reducer’s accumulator are listed in the
+     *  documentation for that particular kind of reducer.)
+     *
+     *  @note   `*r` is a synonym for `r.view()`. Recommended style is to use
+     *          `*r` (or `r->`) in the common case where code is simply
+     *          updating the accumulator variable wrapped in the view, and to
+     *          use `r.view()` in the unusual case where it is desirable to
+     *          call attention to the view itself.
+     */
+    //@{
+    
+    //@{
+    /** Dereference operator.
+     *
+     *  @return A reference to the per-strand view instance.
+     */
+    view_type&       operator*()       { return view(); }
+    view_type const& operator*() const { return view(); }
+    //@}
+
+    //@{
+    /** Pointer operator.
+     *
+     *  @return A pointer to the per-strand view instance.
+     */
+    view_type*       operator->()       { return &view(); }
+    view_type const* operator->() const { return &view(); }
+    //@}
+    
+    //@{
+    /** Deprecated view access.
+     *
+     *  `r()` is a synonym for `*r` which was used with early versions of Cilk
+     *  reducers. `*r` is now the preferred usage.
+     *
+     *  @deprecated Use operator*() instead of operator()().
+     *
+     *  @return A reference to the per-strand view instance.
+     */
+    view_type&       operator()()       { return view(); }
+    view_type const& operator()() const { return view(); }
+    //@}
+    
+    //@}
+    
+    /** @name Set and get the value.
+     *
+     *  These functions are used to set an initial value for the reducer before
+     *  starting the reduction, or to get the final value after the reduction
+     *  is complete.
+     *
+     *  @note   These functions are completely different from the view
+     *          operations that are made available via operator*() and
+     *          operator->(), which are used to _modify_ the reducer’s value
+     *          _during_ the reduction.
+     *
+     *  @warning    These functions _can_ be called at any time, and in 
+     *              general, they will refer to the value contained in the view
+     *              for the current strand. However, using them other than to
+     *              set the reduction’s initial value or get its final value
+     *              will almost always result in undefined behavior.
+     */
+    //@{
+
+    /** Move a value into the reducer.
+     *
+     *  This function is used to set the initial value of the reducer’s
+     *  accumulator variable by either copying or _moving_ the value of @a obj
+     *  into it. Moving a value can often be performed in constant time, even
+     *  for large container objects, but has the side effect of leaving the
+     *  value of @a obj undefined. (See the description of the 
+     *  @ref move_in_wrapper class for a discussion of moving values.) 
+     *
+     *  @par    Usage
+     *          A move_in() call to initialize a reducer is often paired with a
+     *          move_out() call to get its final value:
+     *
+     *              reducer<Type> xr;
+     *              xr.move_in(x);
+     *              … do the reduction …
+     *              xr.move_out(x);
+     *
+     *  @par Assumptions
+     *      -   You cannot assume either that this will function will copy its
+     *          value or that it will move it. 
+     *      -   You must assume that the value of @a obj will be undefined 
+     *          after the call to move_in(). 
+     *      -   You can assume that move_in() will be at least as efficient as
+     *          set_value(), and you should therefore prefer move_in() unless
+     *          you need the value of @a obj to be unchanged after the call.
+     *          (But you should usually prefer the move-in constructor over a
+     *          move_in() call — see the note below.)
+     *
+     *  @note   The behavior of a default constructor followed by move-in
+     *          initialization:
+     *
+     *              reducer<Type> xr;
+     *              xr.move_in(x);
+     *
+     *  @note   is not necessarily the same as a move-in constructor:
+     *
+     *      reducer<Type> xr(move_in(x));
+     * 
+     *  @note   In particular, when @a Type is a container type with a 
+     *          non-empty allocator, the move-in constructor will create the
+     *          accumulator variable with the same allocator as the input
+     *          argument @a x, while the default constructor will create the
+     *          accumulator variable with a default allocator. The mismatch of
+     *          allocators in the latter case means that the input argument 
+     *          @a x may have to be copied in linear time instead of being 
+     *          moved in constant time.
+     *
+     *  @note   Best practice is to prefer the move-in constructor over the
+     *          move-in function unless the move-in function is required for
+     *          some specific reason.
+     *
+     *  @warning    Calling this function other than to set the initial value
+     *              for a reduction will almost always result in undefined
+     *              behavior.
+     *
+     *  @param  obj The object containing the value that will be moved into the
+     *              reducer.
+     *
+     *  @post   The reducer contains the value that was initially in @a obj.
+     *  @post   The value of @a obj is undefined.
+     *
+     *  @see set_value()
+     */
+    void move_in(value_type& obj) { set_get::move_in(view(), obj);}
+
+    /** Move the value out of the reducer.
+     *
+     *  This function is used to retrieve the final value of the reducer’s
+     *  accumulator variable by either copying or _moving_ the value of @a obj
+     *  into it. Moving a value can often be performed in constant time, even
+     *  for large container objects, but has the side effect of leaving the
+     *  value of the reducer’s accumulator variable undefined. (See the
+     *  description of the @ref move_in_wrapper class for a discussion of 
+     *  moving values.) 
+     *
+     *  @par    Usage
+     *          A move_in() call to initialize a reducer is often paired with a
+     *          move_out() call to get its final value:
+     *
+     *              reducer<Type> xr;
+     *              xr.move_in(x);
+     *              … do the reduction …
+     *              xr.move_out(x);
+     *
+     *  @par Assumptions
+     *      -   You cannot assume either that this will function will copy its
+     *          value or that it will move it. 
+     *      -   You must assume that the value of the reducer’s accumulator
+     *          variable will be undefined after the call to move_out().
+     *      -   You can assume that move_out() will be at least as efficient as
+     *          get_value(), and you should therefore prefer move_out() unless
+     *          you need the accumulator variable to be preserved after the
+     *          call.
+     *
+     *  @warning    Calling this function other than to retrieve the final 
+     *              value of a reduction will almost always result in undefined
+     *              behavior.
+     *
+     *  @param  obj The object that the value of the reducer will be moved into.
+     *
+     *  @post   @a obj contains the value that was initially in the reducer.
+     *  @post   The value of the reducer is undefined.
+     *
+     *  @see get_value()
+     */
+    void move_out(value_type& obj) { set_get::move_out(view(), obj); }
+
+    /** Set the value of the reducer.
+     *
+     *  This function sets the initial value of the reducer’s accumulator
+     *  variable to the value of @a obj.
+     *
+     *  @note   The behavior of a default constructor followed by
+     *          initialization:
+     *
+     *      reducer<Type> xr;
+     *      xr.set_value(x);
+     *
+     *  @note   is not necessarily the same as a value constructor:
+     *
+     *      reducer<Type> xr(x);
+     * 
+     *  @note   In particular, when @a Type is a container type with a 
+     *          non-empty allocator, the value constructor will create the
+     *          accumulator variable with the same allocator as the input
+     *          argument @a x, while the default constructor will create the
+     *          accumulator variable with a default allocator.
+     *
+     *  @warning    Calling this function other than to set the initial value
+     *              for a reduction will almost always result in undefined
+     *              behavior.
+     *
+     *  @param  obj The object containing the value that will be copied into 
+     *              the reducer.
+     *
+     *  @post   The reducer contains a copy of the value in @a obj.
+     *
+     *  @see move_in()
+     */
+    void set_value(const value_type& obj) { set_get::set_value(view(), obj); }
+
+    /** Get the value of the reducer.
+     *
+     *  This function gets the final value of the reducer’s accumulator
+     *  variable.
+     *
+     *  @warning    Calling this function other than to retrieve the final 
+     *              value of a reduction will almost always result in undefined
+     *              behavior.
+     *
+     *  @return     A reference to the value contained in the reducer.
+     *
+     *  @see move_out()
+     */
+    typename set_get::get_value_type get_value() const 
+        { return set_get::get_value(view()); }
+    
+    //@}
+
+    /** Implicit downcast to legacy reducer wrapper, if any.
+     *
+     *  @see legacy_reducer_downcast
+     */
+    operator typename legacy_reducer_downcast<reducer>::type& ()
+    {
+        typedef typename legacy_reducer_downcast<reducer>::type downcast_type;
+        return *reinterpret_cast<downcast_type*>(this);
+    }
+
+
+    /** Implicit downcast to legacy reducer wrapper, if any.
+     *
+     *  @see legacy_reducer_downcast
+     */
+    operator const typename legacy_reducer_downcast<reducer>::type& () const
+    {
+        typedef typename legacy_reducer_downcast<reducer>::type downcast_type;
+        return *reinterpret_cast<const downcast_type*>(this);
+    }
+};
+
+#ifdef CILK_STUB
+} // namespace stub
+using stub::reducer;
+#endif
+
+} // end namespace cilk
+
+#endif /* __cplusplus */
+
+/** @page page_reducers_in_c Creating and Using Reducers in C
+ *
+ *  @tableofcontents
+ *  
+ *  The Cilk runtime supports reducers written in C as well as in C++. The basic logic is the
+ *  same, but the implementation details are very different. The C++ reducer implementation uses
+ *  templates heavily to create very generic components. The C reducer implementation uses
+ *  macros, which are a much blunter instrument. The most immediate consequence is that the 
+ *  monoid/view/reducer architecture is mostly implicit rather than explicit in C reducers.
+ *  
+ *  @section reducers_c_overview Overview of Using Reducers in C
+ *  
+ *  The basic usage pattern for C reducers is:
+ *  
+ *  1.  Create and initialize a reducer object.
+ *  2.  Tell the Cilk runtime about the reducer.
+ *  3.  Update the value contained in the reducer in a parallel computation.
+ *  4.  Tell the Cilk runtime that you are done with the reducer.
+ *  5.  Retrieve the value from the reducer.
+ *  
+ *  @subsection reducers_c_creation Creating and Initializing a C Reducer
+ *  
+ *  The basic pattern for creating and initializing a reducer object in C is
+ *  
+ *      CILK_C_DECLARE_REDUCER(value-type) reducer-name =
+ *          CILK_C_INIT_REDUCER(value-type,
+ *                              reduce-function,
+ *                              identity-function,
+ *                              destroy-function,
+ *                              initial-value);
+ *                              
+ *  This is simply an initialized definition of a variable named _reducer-name_. The
+ *  @ref CILK_C_DECLARE_REDUCER macro expands to an anonymous `struct` declaration for a reducer 
+ *  object containing a view of type _value-type_, and the @ref CILK_C_INIT_REDUCER macro
+ *  expands to a struct initializer.
+ *  
+ *  @subsection reducers_c_reduce_func Reduce Functions
+ *  
+ *  The reduce function for a reducer is called when a parallel execution strand terminates, to
+ *  combine the values computed by the terminating strand and the strand to its left. It takes
+ *  three arguments:
+ *  
+ *  -   `void* reducer` — the address of the reducer.
+ *  -   `void* left` — the address of the value for the left strand.
+ *  -   `void* right` — the address of the value for the right (terminating) strand.
+ *  
+ *  It must apply the reducer’s reduction operation to the `left` and `right` values, leaving
+ *  the result in the `left` value. The `right` value is undefined after the reduce function
+ *  call.
+ *  
+ *  @subsection reducers_c_identity_func Identity Functions
+ *  
+ *  The identity function for a reducer is called when a parallel execution strand begins, to
+ *  initialize its value to the reducer’s identity value. It takes two arguments:
+ *  
+ *  -   `void* reducer` — the address of the reducer.
+ *  -   `void* v` — the address of a freshly allocated block of memory of size
+ *      `sizeof(value-type)`.
+ *  
+ *  It must initialize the memory pointed to by `v` so that it contains the reducer’s identity 
+ *  value.
+ *  
+ *  @subsection reducers_c_destroy_func Destroy Functions
+ *  
+ *  The destroy function for a reducer is called when a parallel execution strand terminates, to
+ *  do any necessary cleanup before its value is deallocated. It takes two arguments:
+ *  
+ *  -   `void* reducer` — the address of the reducer.
+ *  -   `void* p` — the address of the value for the terminating strand.
+ *  
+ *  It must release any resources belonging to the value pointed to by `p`, to avoid a resource 
+ *  leak when the memory containing the value is deallocated.
+ *  
+ *  The runtime function `__cilkrts_hyperobject_noop_destroy` can be used for the destructor 
+ *  function if the reducer’s values do not need any cleanup.
+ *  
+ *  @subsection reducers_c_register Tell the Cilk Runtime About the Reducer
+ *  
+ *  Call the @ref CILK_C_REGISTER_REDUCER macro to register the reducer with the Cilk runtime:
+ *  
+ *      CILK_C_REGISTER_REDUCER(reducer-name);
+ *  
+ *  The runtime will manage reducer values for all registered reducers when parallel execution 
+ *  strands begin and end.
+ *  
+ *  @subsection reducers_c_update Update the Value Contained in the Reducer
+ *  
+ *  The @ref REDUCER_VIEW macro returns a reference to the reducer’s value for the  current
+ *  parallel strand:
+ *  
+ *      REDUCER_VIEW(reducer-name) = REDUCER_VIEW(reducer-name) OP x;
+ *      
+ *  C++ reducer views restrict access to the wrapped value so that it can only be modified in
+ *  ways consistent with the reducer’s operation. No such protection is provided for C reducers.
+ *  It is
+ *  entirely the responsibility of the user to avoid modifying the value in any
+ *  inappropriate way.
+ *  
+ *  @subsection c_reducers_unregister Tell the Cilk Runtime That You Are Done with the Reducer
+ *  
+ *  When the parallel computation is complete, call the @ref CILK_C_UNREGISTER_REDUCER macro to 
+ *  unregister the reducer with the Cilk runtime:
+ *  
+ *      CILK_C_UNREGISTER_REDUCER(reducer-name);
+ *  
+ *  The runtime will stop managing reducer values for the reducer.
+ *  
+ *  @subsection c_reducers_retrieve Retrieve the Value from the Reducer
+ *  
+ *  When the parallel computation is complete, use the @ref REDUCER_VIEW macro to retrieve the
+ *  final value computed by the reducer.
+ *  
+ *  @subsection reducers_c_example_custom Example — Creating and Using a Custom C Reducer
+ *  
+ *  The `IntList` type represents a simple list of integers.
+ *  
+ *      struct _intListNode {
+ *          int value;
+ *          _intListNode* next;
+ *      } IntListNode;
+ *      typedef struct { IntListNode* head; IntListNode* tail; } IntList;
+ *      
+ *      // Initialize a list to be empty
+ *      void IntList_init(IntList* list) { list->head = list->tail = 0; }
+ *      
+ *      // Append an integer to the list
+ *      void IntList_append(IntList* list, int x) 
+ *      { 
+ *          IntListNode* node = (IntListNode*) malloc(sizeof(IntListNode));
+ *          if (list->tail) list->tail->next = node; else list->head = node;
+ *          list->tail = node;
+ *      }
+ *      
+ *      // Append the right list to the left list, and leave the right list empty
+ *      void IntList_concat(IntList* left, IntList* right)
+ *      {
+ *          if (left->head) {
+ *              left->tail->next = right->head;
+ *              if (right->tail) left->tail = right->tail;
+ *          }
+ *          else {
+ *              *left = *right;
+ *          }
+ *          IntList_init(*right);
+ *      }
+ *      
+ *  This code creates a reducer that supports creating an `IntList` by appending values to it.
+ *  
+ *      void identity_IntList(void* reducer, void* list)
+ *      {
+ *          IntList_init((IntList*)list);
+ *      }
+ *      
+ *      void reduce_IntList(void* reducer, void* left, void* right)
+ *      {
+ *          IntList_concat((IntList*)left, (IntList*)right);
+ *      }
+ *          
+ *      CILK_C_DECLARE_REDUCER(IntList) my_list_int_reducer =
+ *          CILK_C_INIT_REDUCER(IntList,
+ *                              reduce_int_list,
+ *                              identity_int_list,
+ *                              __cilkrts_hyperobject_noop_destroy);
+ *                              // Initial value omitted //
+ *      ListInt_init(&REDUCER_VIEW(my_int_list_reducer));
+ *
+ *      CILK_C_REGISTER_REDUCER(my_int_list_reducer);
+ *      cilk_for (int i = 0; i != n; ++i) {
+ *          IntList_append(&REDUCER_VIEW(my_int_list_reducer), a[i]);
+ *      }
+ *      CILK_C_UNREGISTER_REDUCER(my_int_list_reducer);
+ *      
+ *      IntList result = REDUCER_VIEW(my_int_list_reducer);
+ *
+ *  @section reducers_c_predefined Predefined C Reducers
+ *
+ *  Some of the predefined reducer classes in the Cilk library come with a set of predefined
+ *  macros to provide the same capabilities in C. In general, two macros are provided for each
+ *  predefined reducer family:
+ *
+ *  -   `CILK_C_REDUCER_operation(reducer-name, type-name, initial-value)` — Declares a
+ *      reducer object named _reducer-name_ with initial value _initial-value_ to perform
+ *      a reduction using the _operation_ on values of the type specified by _type-name_.
+ *      This is the equivalent of the general code described in @ref reducers_c_creation :
+ *
+ *          CILK_C_DECLARE_REDUCER(type) reducer-name =
+ *              CILK_C_INIT_REDUCER(type, ..., initial-value);
+ *
+ *      where _type_ is the C type corresponding to _type_name_. See @ref reducers_c_type_names
+ *      below for the _type-names_ that you can use.
+ *
+ *  -   `CILK_C_REDUCER_operation_TYPE(type-name)` — Expands to the `typedef` name for the type
+ *      of the reducer object declared by
+ *      `CILK_C_REDUCER_operation(reducer-name, type-name, initial-value)`.
+ *
+ *  See @ref reducers_c_example_predefined.
+ *
+ *  The predefined C reducers are:
+ *
+ *  |   Operation       |   Name        |   Documentation               |
+ *  |-------------------|---------------|-------------------------------|
+ *  |   addition        |   `OPADD`     |   @ref ReducersAdd            |
+ *  |   bitwise and     |   `OPAND`     |   @ref ReducersAnd            |
+ *  |   bitwise or      |   `OPOR`      |   @ref ReducersOr             |
+ *  |   bitwise xor     |   `OPXOR`     |   @ref ReducersXor            |
+ *  |   multiplication  |   `OPMUL`     |   @ref ReducersMul            |
+ *  |   minimum         |   `MIN`       |   @ref ReducersMinMax         |
+ *  |   minimum & index |   `MIN_INDEX` |   @ref ReducersMinMax         |
+ *  |   maximum         |   `MIN`       |   @ref ReducersMinMax         |
+ *  |   maximum & index |   `MIN_INDEX` |   @ref ReducersMinMax         |
+ *      
+ *  @subsection reducers_c_type_names Numeric Type Names
+ *  
+ *  The type and function names created by the C reducer definition macros incorporate both the
+ *  reducer kind (`opadd`, `opxor`, etc.) and the value type of the reducer (`int`, `double`, 
+ *  etc.). The value type is represented by a _numeric type name_ string. The types supported 
+ *  in C reducers, and their corresponding numeric type names, are given in the following table:
+ *  
+ *  |   Type                |   Numeric Type Name           |
+ *  |-----------------------|-------------------------------|
+ *  |  `char`               |  `char`                       |
+ *  |  `unsigned char`      |  `uchar`                      |
+ *  |  `signed char`        |  `schar`                      |
+ *  |  `wchar_t`            |  `wchar_t`                    |
+ *  |  `short`              |  `short`                      |
+ *  |  `unsigned short`     |  `ushort`                     |
+ *  |  `int`                |  `int`                        |
+ *  |  `unsigned int`       |  `uint`                       |
+ *  |  `unsigned int`       |  `unsigned` (alternate name)  |
+ *  |  `long`               |  `long`                       |
+ *  |  `unsigned long`      |  `ulong`                      |
+ *  |  `long long`          |  `longlong`                   |
+ *  |  `unsigned long long` |  `ulonglong`                  |
+ *  |  `float`              |  `float`                      |
+ *  |  `double`             |  `double`                     |
+ *  |  `long double`        |  `longdouble`                 |
+ *  
+ *  @subsection reducers_c_example_predefined Example — Using a Predefined C Reducer
+ *
+ *  To compute the sum of all the values in an array of `unsigned int`:
+ *
+ *      CILK_C_REDUCER_OPADD(sum, uint, 0);
+ *      CILK_C_REGISTER_REDUCER(sum);
+ *      cilk_for(int i = 0; i != n; ++i) {
+ *          REDUCER_VIEW(sum) += a[i];
+ *      }
+ *      CILK_C_UNREGISTER_REDUCER(sum);
+ *      printf("The sum is %u\n", REDUCER_VIEW(sum));
+ */
+
+ /** @name C language reducer macros
+ *
+ *  These macros are used to declare and work with reducers in C code.
+ *
+ *  @see @ref page_reducers_in_c
+ */
+ //@{
+
+/// @cond internal
+
+/** @name Compound identifier macros.
+ *
+ *  These macros are used to construct an identifier by concatenating two or three identifiers.
+ */
+//@{
+
+/** Expand to an identifier formed by concatenating two identifiers.
+ */
+#define __CILKRTS_MKIDENT(a,b) __CILKRTS_MKIDENT_IMP(a,b,)
+
+/** Expand to an identifier formed by concatenating three identifiers.
+ */
+#define __CILKRTS_MKIDENT3(a,b,c) __CILKRTS_MKIDENT_IMP(a,b,c)
+
+/** Helper macro to do the concatenation.
+ */
+#define __CILKRTS_MKIDENT_IMP(a,b,c) a ## b ## c
+
+//@}
+
+/** Compiler-specific keyword for the “type of” operator.
+ */
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+# define _Typeof __typeof__
+#endif
+
+/** @name Predefined reducer function declaration macros.
+ *
+ *  These macros are used to create the function headers for the identity, reduction,
+ *  and destructor functions for a builtin reducer family. The macro can be followed by
+ *  a semicolon to create a declaration, or by a brace-enclosed body to create a definition.
+ */
+//@{
+
+/** Create an identity function header.
+ *
+ *  @note   The name of the function’s value pointer parameter will always be `v`.
+ *
+ *  @param name The reducer family name.
+ *  @param tn   The type name.
+ */
+#define __CILKRTS_DECLARE_REDUCER_IDENTITY(name,tn)  CILK_EXPORT         \
+    void __CILKRTS_MKIDENT3(name,_identity_,tn)(void* key, void* v)
+
+/** Create a reduction function header.
+ *
+ *  @param name The reducer family name.
+ *  @param tn   The type name.
+ *  @param l    The name to use for the function’s left value pointer parameter.
+ *  @param r    The name to use for the function’s right value pointer parameter.
+ */
+#define __CILKRTS_DECLARE_REDUCER_REDUCE(name,tn,l,r) CILK_EXPORT        \
+    void __CILKRTS_MKIDENT3(name,_reduce_,tn)(void* key, void* l, void* r)
+
+/** Create a destructor function header.
+ *
+ *  @param name The reducer family name.
+ *  @param tn   The type name.
+ *  @param p    The name to use for the function’s value pointer parameter.
+ */
+#define __CILKRTS_DECLARE_REDUCER_DESTROY(name,tn,p) CILK_EXPORT         \
+    void __CILKRTS_MKIDENT3(name,_destroy_,tn)(void* key, void* p)
+
+//@}
+
+/// @endcond
+
+
+/***************************************************************************
+ *              Real implementation
+ ***************************************************************************/
+
+/** Declaration of a C reducer structure type.
+ *
+ *  This macro expands into an anonymous structure declaration for a C reducer structure
+ *  which contains a @a Type value. For example:
+ *
+ *      CILK_C_DECLARE_REDUCER(int) my_add_int_reducer =
+ *          CILK_C_INIT_REDUCER(int, …);
+ *
+ *  @param Type The type of the value contained in the reducer object.
+ *
+ *  @see @ref reducers_c_creation
+ */
+#define CILK_C_DECLARE_REDUCER(Type) struct {                      \
+        __cilkrts_hyperobject_base   __cilkrts_hyperbase;          \
+        __CILKRTS_CACHE_ALIGN Type   value;                        \
+    }
+
+/** Initializer for a C reducer structure.
+ *
+ *  This macro expands into a brace-enclosed structure initializer for a C reducer structure
+ *  that was declared with `CILK_C_DECLARE_REDUCER(Type)`. For example:
+ *
+ *      CILK_C_DECLARE_REDUCER(int) my_add_int_reducer =
+ *          CILK_C_INIT_REDUCER(int, 
+ *                              add_int_reduce, 
+ *                              add_int_identity, 
+ *                              __cilkrts_hyperobject_noop_destroy,
+ *                              0);
+ *
+ *  @param Type     The type of the value contained in the reducer object. Must be the same as
+ *                  the @a Type argument of the CILK_C_DECLARE_REDUCER macro call that created
+ *                  the reducer.
+ *  @param Reduce   The address of the @ref reducers_c_reduce_func "reduce function" for the
+ *                  reducer.
+ *  @param Identity The address of the @ref reducers_c_identity_func "identity function" for
+ *                  the reducer.
+ *  @param Destroy  The address of the @ref reducers_c_destroy_func "destroy function" for the
+ *                  reducer.
+ *  @param ...      The initial value for the reducer. (A single expression if @a Type is a
+ *                  scalar type; a list of values if @a Type is a struct or array type.)
+ *
+ *  @see @ref reducers_c_creation
+ */
+
+#define CILK_C_INIT_REDUCER(Type, Reduce, Identity, Destroy, ...)       \
+    {   {   {   Reduce                                                  \
+            ,   Identity                                                \
+            ,   Destroy                                                 \
+            ,   __cilkrts_hyperobject_alloc                             \
+            ,   __cilkrts_hyperobject_dealloc                           \
+            }                                                           \
+        ,   0                                                           \
+        ,   __CILKRTS_CACHE_LINE__                                      \
+        ,   sizeof(Type)                                                \
+        }                                                               \
+    ,   __VA_ARGS__                                                     \
+    }
+
+/** Register a reducer with the Cilk runtime.
+ *
+ *  The runtime will manage reducer values for all registered reducers when parallel execution 
+ *  strands begin and end. For example:
+ *
+ *      CILK_C_REGISTER_REDUCER(my_add_int_reducer);
+ *      cilk_for (int i = 0; i != n; ++i) {
+ *          …
+ *      }
+ *
+ *  @param Expr The reducer to be registered.
+ *
+ *  @see @ref page_reducers_in_c
+ */
+#define CILK_C_REGISTER_REDUCER(Expr) \
+    __cilkrts_hyper_create(&(Expr).__cilkrts_hyperbase)
+
+/** Unregister a reducer with the Cilk runtime.
+ *
+ *  The runtime will stop managing reducer values for a reducer after it is unregistered. For
+ *  example:
+ *
+ *      cilk_for (int i = 0; i != n; ++i) {
+ *          …
+ *      }
+ *      CILK_C_UNREGISTER_REDUCER(my_add_int_reducer);
+ *
+ *  @param Expr The reducer to be unregistered.
+ *
+ *  @see @ref page_reducers_in_c
+ */
+#define CILK_C_UNREGISTER_REDUCER(Expr) \
+    __cilkrts_hyper_destroy(&(Expr).__cilkrts_hyperbase)
+
+/** Get the current view for a reducer.
+ *
+ *  The `REDUCER_VIEW(reducer-name)` returns a reference to the reducer’s value for the 
+ *  current parallel strand. This can be used to initialize thevalue of the  reducer before it
+ *  is used, to modify the value of the reducer on the current parallel strand, or to retrieve
+ *  the final value of the reducer at the end of the parallel computation.
+ *
+ *      REDUCER_VIEW(my_add_int_reducer) = REDUCER_VIEW(my_add_int_reducer) + x;
+ *
+ *  @note   C++ reducer views restrict access to the wrapped value so that it can only be
+ *  modified in ways consistent with the reducer’s operation. No such protection is provided 
+ *  for C reducers. It is entirely the responsibility of the user to refrain from modifying the
+ *  value in any inappropriate way.
+ *
+ *  @param Expr The reducer whose value is to be returned.
+ *
+ *  @see @ref page_reducers_in_c
+ */
+#define REDUCER_VIEW(Expr) (*(_Typeof((Expr).value)*)               \
+    __cilkrts_hyper_lookup(&(Expr).__cilkrts_hyperbase))
+
+//@} C language reducer macros
+
+#endif // CILK_REDUCER_H_INCLUDED
diff --git a/libcilkrts/include/cilk/reducer_file.h b/libcilkrts/include/cilk/reducer_file.h
new file mode 100644 (file)
index 0000000..75af994
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
diff --git a/libcilkrts/include/cilk/reducer_list.h b/libcilkrts/include/cilk/reducer_list.h
new file mode 100644 (file)
index 0000000..fc0be1e
--- /dev/null
@@ -0,0 +1,1127 @@
+/*  reducer_list.h                  -*- C++ -*-
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file reducer_list.h
+ *
+ *  @brief Defines classes for doing parallel list creation by appending or
+ *  prepending.
+ *
+ *  @ingroup ReducersList
+ *
+ *  @see ReducersList
+ */
+
+#ifndef REDUCER_LIST_H_INCLUDED
+#define REDUCER_LIST_H_INCLUDED
+
+#include <cilk/reducer.h>
+#include <list>
+
+/** @defgroup ReducersList List Reducers
+ *
+ *  List append and prepend reducers allow the creation of a standard list by
+ *  concatenating a set of lists or values in parallel.
+ *
+ *  @ingroup Reducers
+ *
+ *  You should be familiar with @ref pagereducers "Cilk reducers", described in
+ *  file `reducers.md`, and particularly with @ref reducers_using, before trying
+ *  to use the information in this file.
+ *
+ *  @section redlist_usage Usage Example
+ *
+ *      // Create a list containing the labels of the nodes of a tree in
+ *      // “inorder” (left subtree, root, right subtree).
+ *
+ *      struct Tree { Tree* left; Tree* right; string label; ... };
+ *
+ *      list<string> x;
+ *      cilk::reducer< cilk::op_list_append<string> > xr(cilk::move_in(x));
+ *      collect_labels(tree, xr);
+ *      xr.move_out(x);
+ *      
+ *      void collect_labels(Tree* node, 
+ *                          cilk::reducer< cilk::op_list_append<string> >& xr)
+ *      {
+ *          if (node) {
+ *              cilk_spawn collect_labels(node->left, xr);
+ *              xr->push_back(node->label);
+ *              collect_labels(node->right, xr);
+ *              cilk_sync;
+ *          }
+ *      }
+ *
+ *  @section redlist_monoid The Monoid
+ *
+ *  @subsection redlist_monoid_values Value Set
+ *
+ *  The value set of a list reducer is the set of values of the class 
+ *  `std::list<Type, Allocator>`, which we refer to as “the reducer’s list 
+ *  type”.
+ *
+ *  @subsection redlist_monoid_operator Operator
+ *
+ *  The operator of a list append reducer is defined as
+ *
+ *      x CAT y == (every element of x, followed by every element of y)
+ *
+ *  The operator of a list prepend reducer is defined as
+ *
+ *      x RCAT y == (every element of y, followed by every element of x)
+ *
+ *  @subsection redlist_monoid_identity Identity
+ *
+ *  The identity value of a list reducer is the empty list, which is the value 
+ *  of the expression `std::list<Type, Allocator>([allocator])`.
+ *
+ *  @section redlist_operations Operations
+ *
+ *  In the operation descriptions below, the type name `List` refers to the 
+ *  reducer’s string type, `std::list<Type, Allocator>`.
+ *
+ *  @subsection redlist_constructors Constructors
+ *
+ *  Any argument list which is valid for a `std::list` constructor is valid for 
+ *  a list reducer constructor. The usual move-in constructor is also provided:
+ *
+ *      reducer(move_in(List& variable))
+ *
+ *  A list reducer with no constructor arguments, or with only an allocator 
+ *  argument, will initially contain the identity value, an empty list. 
+ *
+ *  @subsection redlist_get_set Set and Get
+ *
+ *      r.set_value(const List& value)
+ *      const List& = r.get_value() const
+ *      r.move_in(List& variable)
+ *      r.move_out(List& variable)
+ *
+ *  @subsection redlist_view_ops View Operations
+ *
+ *  The view of a list append reducer provides the following member functions:
+ *
+ *      void push_back(const Type& element) 
+ *      void insert_back(List::size_type n, const Type& element) 
+ *      template <typename Iter> void insert_back(Iter first, Iter last)
+ *      void splice_back(List& x)
+ *      void splice_back(List& x, List::iterator i)
+ *      void splice_back(List& x, List::iterator first, List::iterator last)
+ *  
+ *  The view of a list prepend reducer provides the following member functions:
+ *
+ *      void push_front(const Type& element) 
+ *      void insert_front(List::size_type n, const Type& element) 
+ *      template <typename Iter> void insert_front(Iter first, Iter last)
+ *      void splice_front(List& x)
+ *      void splice_front(List& x, List::iterator i)
+ *      void splice_front(List& x, List::iterator first, List::iterator last)
+ *
+ *  The `push_back` and `push_front` functions are the same as the
+ *  corresponding `std::list` functions. The `insert_back`, `splice_back`,
+ *  `insert_front`, and `splice_front` functions are the same as the 
+ *  `std::list` `insert` and `splice` functions, with the first parameter
+ *  fixed to the end or beginning of the list, respectively.
+ *
+ *  @section redlist_performance Performance Considerations
+ *
+ *  An efficient reducer requires that combining the values of two views (using 
+ *  the view `reduce()` function) be a constant-time operations. Two lists can
+ *  be merged in constant time using the `splice()` function if they have the
+ *  same allocator. Therefore, the lists for new views are created (by the view
+ *  identity constructor) using the same allocator as the list that was created
+ *  when the reducer was constructed.
+ *
+ *  The performance of adding elements to a list reducer depends on the view 
+ *  operations that are used:
+ *
+ *  *   The `push` functions add a single element to the list, and therefore
+ *      take constant time.
+ *  *   An `insert` function that inserts _N_ elements adds each of them
+ *      individually, and therefore takes _O(N)_ time. 
+ *  *   A `splice` function that inserts _N_ elements just adjusts a couple of
+ *      pointers, and therefore takes constant time, _if the splice is from a
+ *      list with the same allocator as the reducer_. Otherwise, it is
+ *      equivalent to an `insert`, and takes _O(N)_ time.
+ *
+ *  This means that for best performance, if you will be adding elements to a
+ *  list reducer in batches, you should `splice` them from a list having the
+ *  same allocator as the reducer.
+ *
+ *  The reducer `move_in` and `move_out` functions do a constant-time `swap` if
+ *  the variable has the same allocator as the reducer, and a linear-time copy
+ *  otherwise.
+ *  
+ *  Note that the allocator of a list reducer is determined when the reducer is
+ *  constructed. The following two examples may have very different behavior:
+ *
+ *      list<Element, Allocator> a_list;
+ *
+ *      reducer< list_append<Element, Allocator> reducer1(move_in(a_list));
+ *      ... parallel computation ...
+ *      reducer1.move_out(a_list);
+ *
+ *      reducer< list_append<Element, Allocator> reducer2;
+ *      reducer2.move_in(a_list);
+ *      ... parallel computation ...
+ *      reducer2.move_out(a_list);
+ *
+ *  *   `reducer1` will be constructed with the same allocator as `a_list`,
+ *      because the list was was specified in the constructor. The `move_in`
+ *      and`move_out` can therefore be done with a `swap` in constant time.
+ *  *   `reducer2` will be constructed with a _default_ allocator,
+ *      “`Allocator()`”, which may or may not be the same as the allocator of
+ *      `a_list`. Therefore, the `move_in` and `move_out` may have to be done
+ *      with a copy in _O(N)_ time.
+ *  
+ *  (All instances of an allocator type with no internal state (like
+ *  `std::allocator`) are “the same”. You only need to worry about the “same
+ *  allocator” issue when you create list reducers with custom allocator types.)
+ *
+ *  @section redlist_types Type and Operator Requirements
+ *
+ *  `std::list<Type, Allocator>` must be a valid type.
+ */
+
+
+namespace cilk {
+
+namespace internal {
+
+/** @ingroup ReducersList */
+//@{
+
+/** Base class for list append and prepend view classes.
+ *
+ *  @note   This class provides the definitions that are required for a class
+ *          that will be used as the parameter of a @ref list_monoid_base
+ *          specialization. 
+ *
+ *  @tparam Type        The list element type (not the list type).
+ *  @tparam Allocator   The list's allocator class.
+ *
+ *  @see ReducersList
+ *  @see list_monoid_base
+ */
+template <typename Type, typename Allocator>
+class list_view_base
+{
+protected:
+    /// The type of the contained list.
+    typedef std::list<Type, Allocator>  list_type;
+
+    /// The list accumulator variable.
+    list_type m_value;
+
+public:
+
+    /** @name Monoid support.
+     */
+    //@{
+    
+    /// Required by @ref monoid_with_view
+    typedef list_type   value_type;
+
+    /// Required by @ref list_monoid_base
+    Allocator get_allocator() const
+    { 
+        return m_value.get_allocator(); 
+    }
+    
+    //@}
+    
+    
+    /** @name Constructors.
+     */
+    //@{
+    
+    /// Standard list constructor.
+    explicit list_view_base(const Allocator& a = Allocator()) : m_value(a) {}
+    explicit list_view_base(
+        typename list_type::size_type n, 
+        const Type& value = Type(), 
+        const Allocator& a = Allocator() ) : m_value(n, value, a) {}
+    template <typename Iter> 
+    list_view_base(Iter first, Iter last, const Allocator& a = Allocator()) : 
+        m_value(first, last, a) {}
+    list_view_base(const list_type& list) : m_value(list) {}
+
+    /// Move-in constructor.
+    explicit list_view_base(move_in_wrapper<value_type> w)
+        : m_value(w.value().get_allocator())
+    {
+        m_value.swap(w.value());
+    }
+    
+    //@}
+    
+    /** @name Reducer support.
+     */
+    //@{
+    
+    /// Required by reducer::move_in()
+    void view_move_in(value_type& v)
+    {
+        if (m_value.get_allocator() == v.get_allocator())
+            // Equal allocators. Do a (fast) swap.
+            m_value.swap(v);
+        else
+            // Unequal allocators. Do a (slow) copy.
+            m_value = v;
+        v.clear();
+    }
+    
+    /// Required by reducer::move_out()
+    void view_move_out(value_type& v)
+    {
+        if (m_value.get_allocator() == v.get_allocator())
+            // Equal allocators.  Do a (fast) swap.
+            m_value.swap(v);
+        else
+            // Unequal allocators.  Do a (slow) copy.
+            v = m_value;
+        m_value.clear();
+    }
+    
+    /// Required by reducer::set_value()
+    void view_set_value(const value_type& v) { m_value = v; }
+
+    /// Required by reducer::get_value()
+    value_type const& view_get_value()     const { return m_value; }
+    
+    // Required by legacy wrapper get_reference()
+    value_type      & view_get_reference()       { return m_value; }
+    value_type const& view_get_reference() const { return m_value; }
+    
+    //@}
+};
+
+
+/** Base class for list append and prepend monoid classes.
+ *
+ *  The key to efficient reducers is that the `identity` operation, which
+ * creates a new per-strand view, and the `reduce` operation, which combines
+ *  two per-strand views, must be constant-time operations. Two lists can be
+ *  concatenated in constant time only if they have the same allocator.
+ *  Therefore, all the per-strand list accumulator variables must be created
+ *   with the same allocator as the leftmost view list. 
+ *
+ *  This means that a list reduction monoid must have a copy of the allocator
+ *  of the leftmost view’s list, so that it can use it in the `identity`
+ *  operation. This, in turn, requires that list reduction monoids have a
+ *  specialized `construct()` function, which constructs the leftmost view
+ *  before the monoid, and then passes the leftmost view’s allocator to the
+ *  monoid constructor.
+ *
+ *  @tparam View    The list append or prepend view class.
+ *  @tparam Align   If `false` (the default), reducers instantiated on this
+ *                  monoid will be naturally aligned (the Cilk library 1.0
+ *                  behavior). If `true`, reducers instantiated on this monoid
+ *                  will be cache-aligned for binary compatibility with 
+ *                  reducers in Cilk library version 0.9.
+ *
+ *  @see ReducersList
+ *  @see list_view_base
+ */
+template <typename View, bool Align>
+class list_monoid_base : public monoid_with_view<View, Align>
+{
+    typedef typename View::value_type           list_type;
+    typedef typename list_type::allocator_type  allocator_type;
+    allocator_type                              m_allocator;
+    
+    using monoid_base<list_type, View>::provisional;
+    
+public:
+
+    /** Constructor.
+     *
+     *  There is no default constructor for list monoids, because the allocator 
+     *  must always be specified.
+     *
+     *  @param  allocator   The list allocator to be used when
+     *                      identity-constructing new views.
+     */
+    list_monoid_base(const allocator_type& allocator = allocator_type()) :
+        m_allocator(allocator) {}
+
+    /** Create an identity view.
+     *
+     *  List view identity constructors take the list allocator as an argument.
+     *
+     *  @param v    The address of the uninitialized memory in which the view
+     *              will be constructed.
+     */
+    void identity(View *v) const { ::new((void*) v) View(m_allocator); }
+    
+    /** @name construct functions
+     *
+     *  All `construct()` functions first construct the leftmost view, using 
+     *  the optional @a x1, @a x2, and @a x3 arguments that were passed in from
+     *  the reducer constructor. They then call the view’s `get_allocator()`
+     *  function to get the list allocator from its contained list, and pass it
+     *  to the monoid constructor.
+     */
+    //@{
+
+    template <typename Monoid>
+    static void construct(Monoid* monoid, View* view)
+        { provisional( new ((void*)view) View() ).confirm_if( 
+            new ((void*)monoid) Monoid(view->get_allocator()) ); }
+
+    template <typename Monoid, typename T1>
+    static void construct(Monoid* monoid, View* view, const T1& x1)
+        { provisional( new ((void*)view) View(x1) ).confirm_if( 
+            new ((void*)monoid) Monoid(view->get_allocator()) ); }
+
+    template <typename Monoid, typename T1, typename T2>
+    static void construct(Monoid* monoid, View* view, const T1& x1, const T2& x2)
+        { provisional( new ((void*)view) View(x1, x2) ).confirm_if( 
+            new ((void*)monoid) Monoid(view->get_allocator()) ); }
+
+    template <typename Monoid, typename T1, typename T2, typename T3>
+    static void construct(Monoid* monoid, View* view, const T1& x1, const T2& x2, 
+                            const T3& x3)
+        { provisional( new ((void*)view) View(x1, x2, x3) ).confirm_if( 
+            new ((void*)monoid) Monoid(view->get_allocator()) ); }
+
+    //@}
+};
+
+//@}
+
+} // namespace internal
+
+
+/** @ingroup ReducersList */
+//@{
+
+/** The list append reducer view class.
+ *
+ *  This is the view class for reducers created with 
+ *  `cilk::reducer< cilk::op_list_append<Type, Allocator> >`. It holds the
+ *  accumulator variable for the reduction, and allows only append operations
+ *  to be performed on it.
+ *
+ *  @note   The reducer “dereference” operation (`reducer::operator *()`) 
+ *          yields a reference to the view. Thus, for example, the view class’s
+ *          `push_back` operation would be used in an expression like
+ *          `r->push_back(a)`, where `r` is a list append reducer variable.
+ *
+ *  @tparam Type        The list element type (not the list type).
+ *  @tparam Allocator   The list allocator type.
+ *
+ *  @see ReducersList
+ *  @see op_list_append
+ */
+template <class Type, 
+          class Allocator = typename std::list<Type>::allocator_type>
+class op_list_append_view : public internal::list_view_base<Type, Allocator>
+{
+    typedef internal::list_view_base<Type, Allocator>   base;
+    typedef std::list<Type, Allocator>                  list_type;
+    typedef typename list_type::iterator                iterator;
+    
+    iterator end() { return this->m_value.end(); }
+
+public:
+
+    /** @name Constructors.
+     *
+     *  All op_list_append_view constructors simply pass their arguments on to
+     *  the @ref internal::list_view_base base class constructor.
+     *
+     *  @ref internal::list_view_base supports all the std::list constructor
+     *  forms, as well as the reducer move_in constructor form.
+     */
+    //@{
+    
+    op_list_append_view() : base() {}
+    
+    template <typename T1>
+    op_list_append_view(const T1& x1) : base(x1) {}
+    
+    template <typename T1, typename T2>
+    op_list_append_view(const T1& x1, const T2& x2) : base(x1, x2) {}
+    
+    template <typename T1, typename T2, typename T3>
+    op_list_append_view(const T1& x1, const T2& x2, const T3& x3) : 
+        base(x1, x2, x3) {}
+
+    //@}    
+
+    /** @name View modifier operations.
+     */
+    //@{
+    
+    /** Add an element at the end of the list.
+     *
+     *  This is equivalent to `list.push_back(element)`
+     */
+    void push_back(const Type& element) 
+        { this->m_value.push_back(element); }
+
+    /** Insert elements at the end of the list.
+     *
+     *  This is equivalent to `list.insert(list.end(), n, element)`
+     */
+    void insert_back(typename list_type::size_type n, const Type& element) 
+        { this->m_value.insert(end(), n, element); }
+
+    /** Insert elements at the end of the list.
+     *
+     *  This is equivalent to `list.insert(list.end(), first, last)`
+     */
+    template <typename Iter>
+    void insert_back(Iter first, Iter last)
+        { this->m_value.insert(end(), first, last); }
+
+    /** Splice elements at the end of the list.
+     *
+     *  This is equivalent to `list.splice(list.end(), x)`
+     */
+    void splice_back(list_type& x) {
+        if (x.get_allocator() == this->m_value.get_allocator())
+            this->m_value.splice(end(), x);
+        else {
+            insert_back(x.begin(), x.end());
+            x.clear();
+        }
+    }
+
+    /** Splice elements at the end of the list.
+     *
+     *  This is equivalent to `list.splice(list.end(), x, i)`
+     */
+    void splice_back(list_type& x, iterator i) {
+        if (x.get_allocator() == this->m_value.get_allocator())
+            this->m_value.splice(end(), x, i);
+        else {
+            push_back(*i);
+            x.erase(i);
+        }
+    }
+
+    /** Splice elements at the end of the list.
+     *
+     *  This is equivalent to `list.splice(list.end(), x, first, last)`
+     */
+    void splice_back(list_type& x, iterator first, iterator last) {
+        if (x.get_allocator() == this->m_value.get_allocator())
+            this->m_value.splice(end(), x, first, last);
+        else {
+            insert_back(first, last);
+            x.erase(first, last);
+        }
+    }
+    
+    //@}
+
+    /** Reduction operation.
+     *
+     *  This function is invoked by the @ref op_list_append monoid to combine
+     *  the views of two strands when the right strand merges with the left 
+     *  one. It appends the value contained in the right-strand view to the 
+     *  value contained in the left-strand view, and leaves the value in the
+     *  right-strand view undefined.
+     *
+     *  @param  right   A pointer to the right-strand view. (`this` points to
+     *                  the left-strand view.)
+     *
+     *  @note   Used only by the @ref op_list_append monoid to implement the
+     *          monoid reduce operation.
+     */
+    void reduce(op_list_append_view* right)
+    {
+        __CILKRTS_ASSERT(
+            this->m_value.get_allocator() == right->m_value.get_allocator());
+        this->m_value.splice(end(), right->m_value);
+    }
+};
+
+
+/** The list prepend reducer view class.
+ *
+ *  This is the view class for reducers created with 
+ *  `cilk::reducer< cilk::op_list_prepend<Type, Allocator> >`. It holds the
+ *  accumulator variable for the reduction, and allows only prepend operations
+ *  to be performed on it.
+ *
+ *  @note   The reducer “dereference” operation (`reducer::operator *()`) 
+ *          yields a reference to the view. Thus, for example, the view class’s
+ *          `push_front` operation would be used in an expression like
+ *          `r->push_front(a)`, where `r` is a list prepend reducer variable.
+ *
+ *  @tparam Type        The list element type (not the list type).
+ *  @tparam Allocator   The list allocator type.
+ *
+ *  @see ReducersList
+ *  @see op_list_prepend
+ */
+template <class Type, 
+          class Allocator = typename std::list<Type>::allocator_type>
+class op_list_prepend_view : public internal::list_view_base<Type, Allocator>
+{
+    typedef internal::list_view_base<Type, Allocator>   base;
+    typedef std::list<Type, Allocator>                  list_type;
+    typedef typename list_type::iterator                iterator;
+    
+    iterator begin() { return this->m_value.begin(); }
+
+public:
+
+    /** @name Constructors.
+     *
+     *  All op_list_prepend_view constructors simply pass their arguments on to
+     *  the @ref internal::list_view_base base class constructor.
+     *
+     *  @ref internal::list_view_base supports all the std::list constructor
+     *  forms, as well as the reducer move_in constructor form.
+     *
+     */
+    //@{
+    
+    op_list_prepend_view() : base() {}
+    
+    template <typename T1>
+    op_list_prepend_view(const T1& x1) : base(x1) {}
+    
+    template <typename T1, typename T2>
+    op_list_prepend_view(const T1& x1, const T2& x2) : base(x1, x2) {}
+    
+    template <typename T1, typename T2, typename T3>
+    op_list_prepend_view(const T1& x1, const T2& x2, const T3& x3) : 
+        base(x1, x2, x3) {}
+
+    //@}    
+
+    /** @name View modifier operations.
+     */
+    //@{
+    
+    /** Add an element at the beginning of the list.
+     *
+     *  This is equivalent to `list.push_front(element)`
+     */
+    void push_front(const Type& element) 
+        { this->m_value.push_front(element); }
+
+    /** Insert elements at the beginning of the list.
+     *
+     *  This is equivalent to `list.insert(list.begin(), n, element)`
+     */
+    void insert_front(typename list_type::size_type n, const Type& element) 
+        { this->m_value.insert(begin(), n, element); }
+
+    /** Insert elements at the beginning of the list.
+     *
+     *  This is equivalent to `list.insert(list.begin(), first, last)`
+     */
+    template <typename Iter>
+    void insert_front(Iter first, Iter last)
+        { this->m_value.insert(begin(), first, last); }
+
+    /** Splice elements at the beginning of the list.
+     *
+     *  This is equivalent to `list.splice(list.begin(), x)`
+     */
+    void splice_front(list_type& x) {
+        if (x.get_allocator() == this->m_value.get_allocator())
+            this->m_value.splice(begin(), x);
+        else {
+            insert_front(x.begin(), x.begin());
+            x.clear();
+        }
+    }
+
+    /** Splice elements at the beginning of the list.
+     *
+     *  This is equivalent to `list.splice(list.begin(), x, i)`
+     */
+    void splice_front(list_type& x, iterator i) {
+        if (x.get_allocator() == this->m_value.get_allocator())
+            this->m_value.splice(begin(), x, i);
+        else {
+            push_front(*i);
+            x.erase(i);
+        }
+    }
+
+    /** Splice elements at the beginning of the list.
+     *
+     *  This is equivalent to `list.splice(list.begin(), x, first, last)`
+     */
+    void splice_front(list_type& x, iterator first, iterator last) {
+        if (x.get_allocator() == this->m_value.get_allocator())
+            this->m_value.splice(begin(), x, first, last);
+        else {
+            insert_front(first, last);
+            x.erase(first, last);
+        }
+    }
+    
+    //@}
+
+    /** Reduction operation.
+     *
+     *  This function is invoked by the @ref op_list_prepend monoid to combine
+     *  the views of two strands when the right strand merges with the left 
+     *  one. It prepends the value contained in the right-strand view to the 
+     *  value contained in the left-strand view, and leaves the value in the
+     *  right-strand view undefined.
+     *
+     *  @param  right   A pointer to the right-strand view. (`this` points to
+     *                  the left-strand view.)
+     *
+     *  @note   Used only by the @ref op_list_prepend monoid to implement the
+     *          monoid reduce operation.
+     */
+    /** Reduce operation.
+     *
+     *  Required by @ref monoid_base.
+     */
+    void reduce(op_list_prepend_view* right)
+    {
+        __CILKRTS_ASSERT(
+            this->m_value.get_allocator() == right->m_value.get_allocator());
+        this->m_value.splice(begin(), right->m_value);
+    }
+};
+
+
+
+/** Monoid class for list append reductions. Instantiate the cilk::reducer
+ *  template class with a op_list_append monoid to create a list append reducer
+ *  class. For example, to create a list of strings:
+ *
+ *      cilk::reducer< cilk::op_list_append<std::string> > r;
+ *
+ *  @tparam Type    The list element type (not the list type).
+ *  @tparam Alloc   The list allocator type.
+ *  @tparam Align   If `false` (the default), reducers instantiated on this
+ *                  monoid will be naturally aligned (the Cilk library 1.0
+ *                  behavior). If `true`, reducers instantiated on this monoid
+ *                  will be cache-aligned for binary compatibility with 
+ *                  reducers in Cilk library version 0.9.
+ *
+ *  @see ReducersList
+ *  @see op_list_append_view
+ */
+template <typename Type, 
+          typename Allocator = typename std::list<Type>::allocator_type,
+          bool Align = false>
+struct op_list_append : 
+    public internal::list_monoid_base<op_list_append_view<Type, Allocator>, Align> 
+{
+    /// Construct with default allocator.
+    op_list_append() {}
+    /// Construct with specified allocator.
+    op_list_append(const Allocator& alloc) : 
+        internal::list_monoid_base<op_list_append_view<Type, Allocator>, Align>(alloc) {}
+};
+
+/** Monoid class for list prepend reductions. Instantiate the cilk::reducer
+ *  template class with a op_list_prepend monoid to create a list prepend
+ *  reducer class. For example, to create a list of strings:
+ *
+ *      cilk::reducer< cilk::op_list_prepend<std::string> > r;
+ *
+ *  @tparam Type    The list element type (not the list type).
+ *  @tparam Alloc   The list allocator type.
+ *  @tparam Align   If `false` (the default), reducers instantiated on this
+ *                  monoid will be naturally aligned (the Cilk library 1.0
+ *                  behavior). If `true`, reducers instantiated on this monoid
+ *                  will be cache-aligned for binary compatibility with 
+ *                  reducers in Cilk library version 0.9.
+ *
+ *  @see ReducersList
+ *  @see op_list_prepend_view
+ */
+template <typename Type, 
+          typename Allocator = typename std::list<Type>::allocator_type,
+          bool Align = false>
+struct op_list_prepend : 
+    public internal::list_monoid_base<op_list_prepend_view<Type, Allocator>, Align> 
+{
+    /// Construct with default allocator.
+    op_list_prepend() {}
+    /// Construct with specified allocator.
+    op_list_prepend(const Allocator& alloc) : 
+        internal::list_monoid_base<op_list_prepend_view<Type, Allocator>, Align>(alloc) {}
+};
+
+
+/** Deprecated list append reducer wrapper class.
+ *
+ *  reducer_list_append is the same as 
+ *  @ref reducer<@ref op_list_append>, except that reducer_list_append is a
+ *  proxy for the contained view, so that accumulator variable update 
+ *  operations can be applied directly to the reducer. For example, an element
+ *  is appended to a `reducer<%op_list_append>` with `r->push_back(a)`, but an
+ *  element can be appended to a `%reducer_list_append` with `r.push_back(a)`.
+ *
+ *  @deprecated Users are strongly encouraged to use `reducer<monoid>`
+ *              reducers rather than the old wrappers like reducer_list_append. 
+ *              The `reducer<monoid>` reducers show the reducer/monoid/view
+ *              architecture more clearly, are more consistent in their
+ *              implementation, and present a simpler model for new
+ *              user-implemented reducers.
+ *
+ *  @note   Implicit conversions are provided between `%reducer_list_append` 
+ *          and `reducer<%op_list_append>`. This allows incremental code
+ *          conversion: old code that used `%reducer_list_append` can pass a
+ *          `%reducer_list_append` to a converted function that now expects a
+ *          pointer or reference to a `reducer<%op_list_append>`, and vice
+ *          versa.
+ *
+ *  @tparam Type        The value type of the list.
+ *  @tparam Allocator   The allocator type of the list.
+ *
+ *  @see op_list_append
+ *  @see reducer
+ *  @see ReducersList
+ */
+template <class Type, class Allocator = std::allocator<Type> >
+class reducer_list_append : 
+    public reducer<op_list_append<Type, Allocator, true> >
+{
+    typedef reducer<op_list_append<Type, Allocator, true> > base;
+    using base::view;
+public:
+
+    /// The reducer’s list type.
+    typedef typename base::value_type list_type;
+
+    /// The list’s element type.
+    typedef Type list_value_type;
+
+    /// The reducer’s primitive component type.
+    typedef Type basic_value_type;
+
+    /// The monoid type.
+    typedef typename base::monoid_type Monoid;
+
+    /** @name Constructors
+     */
+    //@{
+    
+    /** Construct a reducer with an empty list.
+     */
+    reducer_list_append() {}
+
+    /** Construct a reducer with a specified initial list value.
+     */
+    reducer_list_append(const std::list<Type, Allocator> &initial_value) : 
+        base(initial_value) {}
+        
+    //@}
+        
+
+    /** @name Forwarded functions
+     *  @details Functions that update the contained accumulator variable are
+     *  simply forwarded to the contained @ref op_and_view. */
+    //@{
+
+    /// @copydoc op_list_append_view::push_back(const Type&)
+    void push_back(const Type& element) { view().push_back(element); }
+    
+    //@}
+
+    /** Allow mutable access to the list within the current view.
+     * 
+     *  @warning    If this method is called before the parallel calculation is
+     *              complete, the list returned by this method will be a partial
+     *              result.
+     * 
+     *  @returns    A mutable reference to the list within the current view.
+     */
+    list_type &get_reference() { return view().view_get_reference(); }
+
+    /** Allow read-only access to the list within the current view.
+     * 
+     *  @warning    If this method is called before the parallel calculation is
+     *              complete, the list returned by this method will be a partial
+     *              result.
+     * 
+     *  @returns    A const reference to the list within the current view.
+     */
+    list_type const &get_reference() const { return view().view_get_reference(); }
+
+    /// @name Dereference
+    //@{
+    /** Dereferencing a wrapper is a no-op. It simply returns the wrapper.
+     *  Combined with the rule that a wrapper forwards view operations to the
+     *  view, this means that view operations can be written the same way on
+     *  reducers and wrappers, which is convenient for incrementally
+     *  converting code using wrappers to code using reducers. That is:
+     *
+     *      reducer< op_list_append<int> > r;
+     *      r->push_back(a);    // *r returns the view
+     *                          // push_back is a view member function
+     *
+     *      reducer_list_append<int> w;
+     *      w->push_back(a);    // *w returns the wrapper
+     *                          // push_back is a wrapper member function that
+     *                          // calls the corresponding view function
+     */
+    //@{
+    reducer_list_append&       operator*()       { return *this; }
+    reducer_list_append const& operator*() const { return *this; }
+
+    reducer_list_append*       operator->()       { return this; }
+    reducer_list_append const* operator->() const { return this; }
+    //@}
+    
+    /** @name Upcast
+     *  @details In Cilk library 0.9, reducers were always cache-aligned. In
+     *  library  1.0, reducer cache alignment is optional. By default, reducers
+     *  are unaligned (i.e., just naturally aligned), but legacy wrappers
+     *  inherit from cache-aligned reducers for binary compatibility.
+     *
+     *  This means that a wrapper will automatically be upcast to its aligned
+     *  reducer base class. The following conversion operators provide
+     *  pseudo-upcasts to the corresponding unaligned reducer class.
+     */
+    //@{
+    operator reducer< op_list_append<Type, Allocator, false> >& ()
+    {
+        return *reinterpret_cast<
+            reducer< op_list_append<Type, Allocator, false> >*
+            >(this);
+    }
+    operator const reducer< op_list_append<Type, Allocator, false> >& () const
+    {
+        return *reinterpret_cast< 
+            const reducer< op_list_append<Type, Allocator, false> >* 
+            >(this);
+    }
+    //@}
+    
+};
+
+
+/** Deprecated list prepend reducer wrapper class.
+ *
+ *  reducer_list_prepend is the same as 
+ *  @ref reducer<@ref op_list_prepend>, except that reducer_list_prepend is a
+ *  proxy for the contained view, so that accumulator variable update operations
+ *  can be applied directly to the reducer. For example, an element is prepended
+ *  to a `reducer<op_list_prepend>` with `r->push_back(a)`, but an element is
+ *  prepended to a `reducer_list_prepend` with `r.push_back(a)`.
+ *
+ *  @deprecated Users are strongly encouraged to use `reducer<monoid>`
+ *              reducers rather than the old wrappers like reducer_list_prepend. 
+ *              The `reducer<monoid>` reducers show the reducer/monoid/view
+ *              architecture more clearly, are more consistent in their
+ *              implementation, and present a simpler model for new
+ *              user-implemented reducers.
+ *
+ *  @note   Implicit conversions are provided between `%reducer_list_prepend` 
+ *          and `reducer<%op_list_prepend>`. This allows incremental code
+ *          conversion: old code that used `%reducer_list_prepend` can pass a
+ *          `%reducer_list_prepend` to a converted function that now expects a
+ *          pointer or reference to a `reducer<%op_list_prepend>`, and vice
+ *          versa.
+ *
+ *  @tparam Type        The value type of the list.
+ *  @tparam Allocator   The allocator type of the list.
+ *
+ *  @see op_list_prepend
+ *  @see reducer
+ *  @see ReducersList
+ */
+template <class Type, class Allocator = std::allocator<Type> >
+class reducer_list_prepend : 
+    public reducer<op_list_prepend<Type, Allocator, true> >
+{
+    typedef reducer<op_list_prepend<Type, Allocator, true> > base;
+    using base::view;
+public:
+
+    /** The reducer’s list type.
+     */
+    typedef typename base::value_type list_type;
+
+    /** The list’s element type.
+     */
+    typedef Type list_value_type;
+
+    /** The reducer’s primitive component type.
+     */
+    typedef Type basic_value_type;
+
+    /** The monoid type.
+     */
+    typedef typename base::monoid_type Monoid;
+
+    /** @name Constructors
+     */
+    //@{
+    
+    /** Construct a reducer with an empty list.
+     */
+    reducer_list_prepend() {}
+
+    /** Construct a reducer with a specified initial list value.
+     */
+    reducer_list_prepend(const std::list<Type, Allocator> &initial_value) : 
+        base(initial_value) {}
+        
+    //@}
+
+    /** @name Forwarded functions
+     *  @details Functions that update the contained accumulator variable are
+     *  simply forwarded to the contained @ref op_and_view. 
+     */
+    //@{
+
+    /// @copydoc op_list_prepend_view::push_front(const Type&)
+    void push_front(const Type& element) { view().push_front(element); }
+    
+    //@}
+
+    /** Allow mutable access to the list within the current view.
+     * 
+     *  @warning    If this method is called before the parallel calculation is
+     *              complete, the list returned by this method will be a partial
+     *              result.
+     * 
+     *  @returns    A mutable reference to the list within the current view.
+     */
+    list_type &get_reference() { return view().view_get_reference(); }
+
+    /** Allow read-only access to the list within the current view.
+     * 
+     *  @warning    If this method is called before the parallel calculation is
+     *              complete, the list returned by this method will be a partial
+     *              result.
+     * 
+     *  @returns    A const reference to the list within the current view.
+     */
+    list_type const &get_reference() const { return view().view_get_reference(); }
+
+    /// @name Dereference
+    /** Dereferencing a wrapper is a no-op. It simply returns the wrapper.
+     *  Combined with the rule that a wrapper forwards view operations to the
+     *  view, this means that view operations can be written the same way on
+     *  reducers and wrappers, which is convenient for incrementally
+     *  converting code using wrappers to code using reducers. That is:
+     *
+     *      reducer< op_list_prepend<int> > r;
+     *      r->push_front(a);    // *r returns the view
+     *                           // push_front is a view member function
+     *
+     *      reducer_list_prepend<int> w;
+     *      w->push_front(a);    // *w returns the wrapper
+     *                           // push_front is a wrapper member function that
+     *                           // calls the corresponding view function
+     */
+    //@{
+    reducer_list_prepend&       operator*()       { return *this; }
+    reducer_list_prepend const& operator*() const { return *this; }
+
+    reducer_list_prepend*       operator->()       { return this; }
+    reducer_list_prepend const* operator->() const { return this; }
+    //@}
+    
+    /** @name Upcast
+     *  @details In Cilk library 0.9, reducers were always cache-aligned. In
+     *  library  1.0, reducer cache alignment is optional. By default, reducers
+     *  are unaligned (i.e., just naturally aligned), but legacy wrappers
+     *  inherit from cache-aligned reducers for binary compatibility.
+     *
+     *  This means that a wrapper will automatically be upcast to its aligned
+     *  reducer base class. The following conversion operators provide
+     *  pseudo-upcasts to the corresponding unaligned reducer class.
+     */
+    //@{
+    operator reducer< op_list_prepend<Type, Allocator, false> >& ()
+    {
+        return *reinterpret_cast<
+            reducer< op_list_prepend<Type, Allocator, false> >* 
+            >(this);
+    }
+    operator const reducer< op_list_prepend<Type, Allocator, false> >& () const
+    {
+        return *reinterpret_cast<
+            const reducer< op_list_prepend<Type, Allocator, false> >* 
+            >(this);
+    }
+    //@}
+    
+};
+
+/// @cond internal
+
+/** Metafunction specialization for reducer conversion.
+ *
+ *  This specialization of the @ref legacy_reducer_downcast template class
+ *  defined in reducer.h causes the `reducer< op_list_append<Type, Allocator> >`
+ *  class to have an `operator reducer_list_append<Type, Allocator>& ()`
+ *  conversion operator that statically downcasts the `reducer<op_list_append>`
+ *  to the corresponding `reducer_list_append` type. (The reverse conversion,
+ *  from `reducer_list_append` to `reducer<op_list_append>`, is just an upcast,
+ *  which is provided for free by the language.)
+ */
+template <class Type, class Allocator, bool Align>
+struct legacy_reducer_downcast<reducer<op_list_append<Type, Allocator, Align> > >
+{
+    typedef reducer_list_append<Type, Allocator> type;
+};
+
+/** Metafunction specialization for reducer conversion.
+ *
+ *  This specialization of the @ref legacy_reducer_downcast template class
+ *  defined in reducer.h causes the
+ *  `reducer< op_list_prepend<Type, Allocator> >` class to have an 
+ *  `operator reducer_list_prepend<Type, Allocator>& ()` conversion operator
+ *  that statically downcasts the `reducer<op_list_prepend>` to the
+ *  corresponding `reducer_list_prepend` type. (The reverse conversion, from
+ *  `reducer_list_prepend` to `reducer<op_list_prepend>`, is just an upcast,
+ *  which is provided for free by the language.)
+ */
+template <class Type, class Allocator, bool Align>
+struct legacy_reducer_downcast<reducer<op_list_prepend<Type, Allocator, Align> > >
+{
+    typedef reducer_list_prepend<Type, Allocator> type;
+};
+
+/// @endcond
+
+//@}
+
+} // Close namespace cilk
+
+#endif //  REDUCER_LIST_H_INCLUDED
diff --git a/libcilkrts/include/cilk/reducer_max.h b/libcilkrts/include/cilk/reducer_max.h
new file mode 100644 (file)
index 0000000..3ba3a0b
--- /dev/null
@@ -0,0 +1,46 @@
+/*  reducer_max.h                  -*- C++ -*-
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file reducer_max.h
+ *
+ *  @brief Defines classes for doing parallel maximum reductions.
+ *
+ *  @ingroup ReducersMinMax
+ *
+ *  @see ReducersMinMax
+ */
+
+#include "reducer_min_max.h"
diff --git a/libcilkrts/include/cilk/reducer_min.h b/libcilkrts/include/cilk/reducer_min.h
new file mode 100644 (file)
index 0000000..f5a3910
--- /dev/null
@@ -0,0 +1,46 @@
+/*  reducer_min.h                  -*- C++ -*-
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file reducer_min.h
+ *
+ *  @brief Defines classes for doing parallel minimum reductions.
+ *
+ *  @ingroup ReducersMinMax
+ *
+ *  @see ReducersMinMax
+ */
+
+#include "reducer_min_max.h"
diff --git a/libcilkrts/include/cilk/reducer_min_max.h b/libcilkrts/include/cilk/reducer_min_max.h
new file mode 100644 (file)
index 0000000..55f068c
--- /dev/null
@@ -0,0 +1,3606 @@
+/*  reducer_min_max.h                  -*- C++ -*-
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file reducer_min_max.h
+ *
+ *  @brief Defines classes for doing parallel minimum and maximum reductions.
+ *
+ *  @ingroup ReducersMinMax
+ *
+ *  @see ReducersMinMax
+ */
+
+#ifndef REDUCER_MIN_MAX_H_INCLUDED
+#define REDUCER_MIN_MAX_H_INCLUDED
+
+#include <cilk/reducer.h>
+
+#ifdef __cplusplus
+
+#include <algorithm>
+#include <limits>
+
+/** @defgroup ReducersMinMax Minimum and Maximum Reducers
+ *
+ *  Minimum and maximum reducers allow the computation of the minimum or
+ *  maximum of a set of values in parallel.
+ *
+ *  @ingroup Reducers
+ *
+ *  You should be familiar with @ref pagereducers "Cilk reducers", described in
+ *  file `reducers.md`, and particularly with @ref reducers_using, before trying
+ *  to use the information in this file.
+ *
+ *  @section redminmax_usage Usage Examples
+ *
+ *      cilk::reducer< cilk::op_max<int> > rm;
+ *      cilk_for (int i = 0; i < ARRAY_SIZE; ++i)
+ *      {
+ *          rm->calc_max(a[i]); // or *rm = cilk::max_of(*max, a[i])
+ *      }
+ *      std::cout << "maximum value is " << rm.get_value() << std::endl;
+ *
+ *  and
+ *
+ *      cilk::reducer< cilk::op_min_index<int, double> > rmi;
+ *      cilk_for (int i = 0; i < ARRAY_SIZE; ++i)
+ *      {
+ *          rmi->calc_min(i, a[i]) // or *rmi = cilk::min_of(*rmi, i, a[i]);
+ *      }
+ *      std::cout << "minimum value a[" << rmi.get_value().first << "] = "
+ *                << rmi.get_value().second << std::endl;
+ *
+ *  @section redminmax_monoid The Monoid
+ *
+ *  @subsection redminmax_monoid_values Value Set
+ *
+ *  The value set of a minimum or maximum reducer is the set of values of
+ *  `Type`, possibly augmented with a special identity value which is greater
+ *  than (less than) any value of `Type`.
+ *
+ *  @subsection redminmax_monoid_operator Operator
+ *
+ *  In the most common case, the operator of a minimum reducer is defined as
+ *
+ *      x MIN y == (x < y) ? x : y
+ *
+ *  Thus, `a1 MIN a2 MIN … an` is the first `ai` which is not greater than any
+ *  other `ai`.
+ *
+ *  The operator of a maximum reducer is defined as
+ *
+ *      x MAX y == (x > y) ? x : y
+ *
+ *  Thus, `a1 MAX a2 MAX … an` is the first `ai` which is not less than any
+ *  other `ai`.
+ *
+ *  @subsection redminmax_monoid_comparators Comparators
+ *
+ *  Min/max reducers are not limited to finding the minimum or maximum value
+ *  determined by the `<` or `>` operator. In fact, all min/max reducers use a
+ *  _comparator_, which is either a function or an object of a function class
+ *  that defines a [strict weak ordering] 
+ *  (http://en.wikipedia.org/wiki/Strict_weak_ordering#Strict_weak_orderings)
+ *  on a set of values. (This is exactly the same as the requirement for the
+ *  comparison predicate for STL associative containers and sorting
+ *  algorithms.)
+ *
+ *  Just as with STL algorithms and containers, the comparator type parameter
+ *  for min/max reducers is optional. If it is omitted, it defaults to
+ *  `std::less`, which gives the behavior described in the previous section.
+ *  Using non-default comparators (anything other than `std::less`) with 
+ *  min/max reducers is just like using them with STL containers and 
+ *  algorithms.
+ *
+ *  Taking comparator objects into account, the reduction operation `MIN` for a
+ *  minimum reducer is defined as
+ *
+ *      x MIN y == compare(x, y) ? x : y
+ *
+ *  where `compare()` is the reducer’s comparator. Similarly, the reduction
+ *  operation MAX for a maximum reducer is defined as
+ *
+ *      x MAX y == compare(y, x) ? x : y
+ *
+ *  (If `compare(x, y) == x < y`, then `compare(y, x) == x > y`.) 
+ *
+ *  @subsection redminmax_monoid_identity Identity
+ *
+ *  The identity value of the reducer is the value which is greater than (less
+ *  than) any other value in the value set of the reducer. This is the 
+ *  [“special identity value”](#redminmax_monoid_values) if the reducer has
+ *  one, or the largest (smallest) value in the value set otherwise.
+ *
+ *  @section redminmax_index Value and Index Reducers
+ *
+ *  Min/max reducers come in two families. The _value_ reducers, using `op_min`
+ *  and `op_max` monoids, simply find the smallest or largest value from a set
+ *  of values. The _index_ reducers, using `op_min_index` and `op_max_index` 
+ *  monoids, also record an index value associated with the first occurrence of
+ *  the smallest or largest value.
+ *
+ *  In the `%op_min_index` usage example [above](#redminmax_usage), the values
+ *  are taken from an array, and the index of a value is the index of the array
+ *  element it comes from. More generally, though, an index can be any sort of
+ *  key which identifies a particular value in a collection of values. For
+ *  example, if the values were taken from the nodes of a tree, then the 
+ *  “index” of a value might be a pointer to the node containing that value. 
+ *
+ *  A min/max index reducer is essentially the same as a min/max value reducer
+ *  whose value type is an (index, value) pair, and whose comparator ignores 
+ *  the index part of the pair. (index, value) pairs are represented by
+ *  `std::pair<Index, Type>` objects. This has the consequence that wherever 
+ *  the interface of a min/max value reducer has a `Type`, the interface of the
+ *  corresponding min/max index reducer has a `std::pair<Index, Type>`. (There
+ *  are convenience variants of the `reducer(Type)` constructor and the
+ *  `calc_min()`, `calc_max()`, `%min_of()`, and `%max_of()` functions that
+ *  take an index argument and a value argument instead of an index/value 
+ *  pair.)
+ *
+ *  @section redminmax_operations Operations
+ *
+ *  @subsection redminmax_constructors Constructors
+ *
+ *  @subsubsection redminmax_constructors_value Min/Max Value Reducers
+ *
+ *      reducer()                           // identity
+ *      reducer(const Compare& compare)     // identity
+ *      reducer(const Type& value)
+ *      reducer(move_in(Type& variable))
+ *      reducer(const Type& value, const Compare& compare)
+ *      reducer(move_in(Type& variable), const Compare& compare)
+ *
+ *  @subsubsection redminmax_constructors_index Min/Max Index Reducers
+ *
+ *      reducer()                           // identity
+ *      reducer(const Compare& compare)     // identity
+ *      reducer(const std::pair<Index, Type>& pair)
+ *      reducer(const Index& index, const Type& value)
+ *      reducer(move_in(std::pair<Index, Type>& variable))
+ *      reducer(const std::pair<Index, Type>& pair, const Compare& compare)
+ *      reducer(const Index& index, const Type& value, const Compare& compare)
+ *      reducer(move_in(std::pair<Index, Type>& variable), const Compare& compare)
+ *
+ *  @subsection redminmax_get_set Set and Get
+ *
+ *      r.set_value(const Type& value)
+ *      Type = r.get_value() const
+ *      r.move_in(Type& variable)
+ *      r.move_out(Type& variable)
+ *
+ *  Note that for an index reducer, the `Type` in these operations is actually a
+ *  `std::pair<Index, Type>`. (See @ref redminmax_index.) There is _not_ a
+ *  `set_value(value, index)` operation.
+ *
+ *  @subsection redminmax_initial Initial Values and is_set()
+ *
+ *  A minimum or maximum reducer without a specified initial value, before any
+ *  MIN or MAX operation has been performed on it, represents the [identity
+ *  value](#redminmax_monoid_identity) of its monoid. For value reducers with a
+ *  numeric type and default comparator (`std::less`), this will be a well
+ *  defined value. For example,
+ *
+ *      reducer< op_max<unsigned> > r1;
+ *      // r1.get_value() == 0
+ *
+ *      reducer< op_min<float> > r2;
+ *      // r2.get_value() == std::numeric_limits<float>::infinity
+ *
+ *  In other cases, though (index reducers, non-numeric types, or non-default
+ *  comparators), the actual identity value for the monoid may be unknown, or
+ *  it may not even be a value of the reducer’s type. For example, there is no
+ *  “largest string” to serve as the initial value for a 
+ *  `reducer< op_min<std::string> >`. In these cases, the result of calling
+ *  `get_value()` is undefined.
+ *
+ *  To avoid calling `get_value()` when its result is undefined, you can call
+ *  the view’s `is_set()` function, which will return true  if the reducer
+ *  has a well-defined value — either because a MIN or MAX operation has been
+ *  performed, or because it had a well-defined initial value:
+ *
+ *      reducer< op_max<unsigned> > r1;
+ *      // r1->is_set() == true
+ *      // r1.get_value() == 0
+ *
+ *      reducer< op_min<std::string> > r2;
+ *      // r2->is_set() == false
+ *      // r2.get_value() is undefined
+ *      r2->calc_min("xyzzy");
+ *      // r2->is_set() == true
+ *      // r2.get_value() == "xyzzy"
+ *
+ *  >   Note: For an index reducer without a specified initial value, the 
+ *  >   initial value of the index is the default value of the `Index` type.
+ *
+ *  @subsection redminmax_view_ops View Operations
+ *
+ *  The basic reduction operation is `x = x MIN a` for a minimum reducer, or 
+ *  `x = x MAX a` for a maximum reducer. The basic syntax for these operations
+ *  uses the `calc_min()` and `calc_max()` member functions of the view class.
+ *  An assignment syntax is also provided, using the %cilk::min_of() and
+ *  %cilk::max_of() global functions:
+ *
+ *  Class          | Modifier            | Assignment
+ *  ---------------|---------------------|-----------
+ *  `op_min`       | `r->calc_min(x)`    | `*r = min_of(*r, x)` or `*r = min_of(x, *r)`
+ *  `op_max`       | `r->calc_max(x)`    | `*r = max_of(*r, x)` or `*r = max_of(x, *r)`
+ *  `op_min_index` | `r->calc_min(i, x)` | `*r = min_of(*r, i, x)` or `*r = min_of(i, x, *r)`
+ *  `op_max_index` | `r->calc_max(i, x)` | `*r = max_of(*r, i, x)` or `*r = max_of(i, x, *r)`
+ *
+ *  Wherever an “`i`, `x`” argument pair is shown in the table above, a single
+ *  pair argument may be passed instead. For example:
+ *
+ *      Index index;
+ *      Type value;
+ *      std::pair<Index, Type> ind_val(index, value);
+ *      // The following statements are all equivalent.
+ *      r->calc_min(index, value);
+ *      r->calc_min(ind_val);
+ *      *r = min_of(*r, index, value);
+ *      *r = min_of(*r, ind_val);
+ *
+ *  The `calc_min()` and `calc_max()` member functions return a reference to 
+ *  the view, so they can be chained:
+ *
+ *      r->calc_max(x).calc_max(y).calc_max(z);
+ *
+ *  In a `%min_of()` or `%max_of()` assignment, the view on the left-hand side
+ *  of the assignment must be the same as the view argument in the call.
+ *  Otherwise, the behavior is undefined (but an assertion error will occur if
+ *  the code is compiled with debugging enabled).
+ *
+ *      *r = max_of(*r, x);     // OK
+ *      *r1 = max_of(*r2, y);   // ERROR
+ *
+ *  `%min_of()` and `%max_of()` calls can be nested:
+ *
+ *      *r = max_of(max_of(max_of(*r, x), y), z);
+ *      *r = min_of(i, a[i], min_of(j, a[j], min_of(k, a[k], *r)));
+ *
+ *  @section redminmax_compatibility Compatibility Issues
+ *
+ *  Most Cilk library reducers provide
+ *  *   Binary compatibility between `reducer_KIND` reducers compiled with Cilk
+ *      library version 0.9 (distributed with Intel® C++ Composer XE version
+ *      13.0 and earlier) and the same reducers compiled with Cilk library
+ *      version 1.0 and later.
+ *  *   Transparent casting between references to `reducer<op_KIND>` and
+ *      `reducer_KIND`.
+ *
+ *  This compatibility is not available in all cases for min/max reducers. 
+ *  There are two areas of incompatibility.
+ *
+ *  @subsection redminmax_compatibility_stateful Non-empty Comparators
+ *
+ *  There is no way to provide binary compatibility between the 0.9 and 1.0
+ *  definitions of min/max reducers that use a non-empty comparator class or a
+ *  comparator function. (Empty comparator classes like `std::less` are not a
+ *  problem.) 
+ *
+ *  To avoid run-time surprises, the legacy `reducer_{min|max}[_index]` classes
+ *  have been coded in the 1.0 library so that they will not even compile when
+ *  instantiated with a non-empty comparator class.
+ *
+ *  @subsection redminmax_compatibility_optimized Numeric Optimization
+ *
+ *  Min/max reducers with a numeric value type and the default comparator can 
+ *  be implemented slightly more efficiently than other min/max reducers.
+ *  However, the optimization is incompatible with the 0.9 library
+ *  implementation of min/max reducers.
+ *
+ *  The default min/max reducers implementation in the 1.0 library uses this
+ *  numeric optimization. Code using legacy reducers compiled with the 1.0
+ *  library can be safely used in the same program as code compiled with the
+ *  0.9 library, but classes compiled with the different Cilk libraries will be
+ *  defined in different namespaces.
+ *
+ *  The simplest solution is just to recompile the code that was compiled with
+ *  the older version of Cilk. However, if this is impossible, you can define
+ *  the `CILK_LIBRARY_0_9_REDUCER_MINMAX` macro (on the compiler command line,
+ *  or in your source code before including `reducer_min_max.h`) when compiling
+ *  with the new library. This will cause it to generate numeric reducers that
+ *  will be less efficient, but will be fully compatible with previously
+ *  compiled code. (Note that this macro has no effect on [the non-empty
+ *  comparator incompatibility] (redminmax_compatibility_stateful).)
+ *
+ *  @section redminmax_types Type Requirements
+ *
+ *  `Type` and `Index` must be `Copy Constructible`, `Default Constructible`,
+ *  and `Assignable`.
+ *
+ *  `Compare` must be `Copy Constructible` if the reducer is constructed with a 
+ *  `compare` argument, and `Default Constructible` otherwise.
+ *
+ *  The `Compare` function must induce a strict weak ordering on the elements
+ *  of `Type`.
+ *
+ *  @section redminmax_in_c Minimum and Maximum Reducers in C
+ *
+ *  These macros can be used to do minimum and maximum reductions in C:
+ *
+ *  Declaration                  | Type                              | Operation
+ *  -----------------------------|-----------------------------------|----------
+ * @ref CILK_C_REDUCER_MIN       |@ref CILK_C_REDUCER_MIN_TYPE       |@ref CILK_C_REDUCER_MIN_CALC      
+ * @ref CILK_C_REDUCER_MAX       |@ref CILK_C_REDUCER_MAX_TYPE       |@ref CILK_C_REDUCER_MAX_CALC      
+ * @ref CILK_C_REDUCER_MIN_INDEX |@ref CILK_C_REDUCER_MIN_INDEX_TYPE |@ref CILK_C_REDUCER_MIN_INDEX_CALC
+ * @ref CILK_C_REDUCER_MAX_INDEX |@ref CILK_C_REDUCER_MAX_INDEX_TYPE |@ref CILK_C_REDUCER_MAX_INDEX_CALC
+ *
+ *  For example:
+ *
+ *      CILK_C_REDUCER_MIN(r, int, INT_MAX);
+ *      CILK_C_REGISTER_REDUCER(r);
+ *      cilk_for(int i = 0; i != n; ++i) {
+ *          CILK_C_REDUCER_MIN_CALC(r, a[i]);
+ *      }
+ *      CILK_C_UNREGISTER_REDUCER(r);
+ *      printf("The smallest value in a is %d\n", REDUCER_VIEW(r));
+ *
+ *
+ *      CILK_C_REDUCER_MAX_INDEX(r, uint, 0);
+ *      CILK_C_REGISTER_REDUCER(r);
+ *      cilk_for(int i = 0; i != n; ++i) {
+ *          CILK_C_REDUCER_MAX_INDEX_CALC(r, i, a[i]);
+ *      }
+ *      CILK_C_UNREGISTER_REDUCER(r);
+ *      printf("The largest value in a is %u at %d\n", 
+ *              REDUCER_VIEW (r).value, REDUCER_VIEW(r).index);
+ *
+ *  See @ref reducers_c_predefined.
+ */
+
+namespace cilk {
+
+/** @defgroup ReducersMinMaxBinComp Binary compatibility
+ *
+ *  If the macro CILK_LIBRARY_0_9_REDUCER_MINMAX is defined, then we generate
+ *  reducer code and data structures which are binary-compatible with code that
+ *  was compiled with the old min/max wrapper definitions, so we want the
+ *  mangled names of the legacy min/max reducer wrapper classes to be the
+ *  same as the names produced by the old definitions.
+ *
+ *  Conversely, if the macro is not defined, then we generate binary- 
+ *  incompatible code, so we want different mangled names, to make sure that 
+ *  the linker does not allow new and old compiled legacy wrappers to be passed
+ *  to one another. (Global variables are a different, and probably insoluble,
+ *  problem.)
+ *
+ *  Similarly, min/max classes compiled with and without 
+ *  CILK_LIBRARY_0_9_REDUCER_MINMAX are binary-incompatible, and must get 
+ *  different mangled names.
+ *
+ *  The trick is, when compiling in normal (non-compatibility) mode, wrap
+ *  everything in an extra namespace, and then `use` it into the top-level cilk
+ *  namespace. Then 
+ *
+ *  *   Classes and functions compiled in normal mode will be in
+ *      different namespaces from the same classes and functions compiled in
+ *      compatibility mode.
+ *  *   The legacy wrapper classes and functions will be in the same namespace 
+ *      as the same classes and functions compiled with the0.9 library if and
+ *      only if the are compiled in compatibility mode.
+ *
+ *  @ingroup ReducersMinMax
+ */
+#ifndef CILK_LIBRARY_0_9_REDUCER_MINMAX
+/** Namespace to wrap min/max reducer definitions when not compiling in “binary
+ *  compatibility” mode.
+ *
+ *  By default, all of the min/max reducer definitions are defined in this
+ *  namespace and then imported into namespace ::cilk, so that they do not
+ *  clash with the legacy definitions with the same names. However, if the
+ *  macro `CILK_LIBRARY_0_9_REDUCER_MINMAX` is defined, then the min/max
+ *  definitions go directly into namespace ::cilk, so that, for example,
+ *  cilk::reducer_max defined with the 1.0 library is equivalent (to the
+ *  linker) to cilk::reducer_max defined with the 0.9 library.
+ *
+ *  @ingroup ReducersMinMaxBinComp
+ *  @ingroup ReducersMinMax
+ */
+namespace cilk_lib_1_0 {
+#endif
+
+/** Namespace containing internal implementation classes and functions for
+ *  min/max reducers.
+ *
+ *  @ingroup ReducersMinMax
+ */
+namespace min_max_internal {
+
+using ::cilk::internal::binary_functor;
+using ::cilk::internal::typed_indirect_binary_function;
+using ::cilk::internal::class_is_empty;
+
+/** @defgroup ReducersMinMaxIsSet The “is_set optimization”
+ *
+ *  The obvious definition of the identity value for a max or min reducer is as
+ *  the smallest (or largest) value of the value type. However, for an 
+ *  arbitrary comparator and/or an arbitrary value type, the largest / smallest
+ *  value may not be known. It may not even be defined — what is the largest
+ *  string?
+ *
+ *  Therefore, min/max reducers represent their value internally as a pair
+ *  `(value, is_set)`. When `is_set` is true, the pair represents the known
+ *  value `value`; when `is_set` is false, the pair represents the identity
+ *  value.
+ *
+ *  This is an effective solution, but the most common use of min/max reducers
+ *  is probably with numeric types and the default definition of minimum or
+ *  maximum (using `std::less`), in which case there are well-defined, knowable
+ *  smallest and largest values. Testing `is_set` for every comparison is then
+ *  unnecessary and wasteful.
+ *
+ *  The “is_set optimization” just means generating code that doesn’t use
+ *  `is_set` when it isn’t needed. It is implemented using two metaprogramming
+ *  classes:
+ *
+ *  -   do_is_set_optimization tests whether the optimization is applicable.
+ *  -   identity_value gets the appropriate identity value for a type.
+ *
+ *  The is_set optimization is the reason that min/max reducers compiled with
+ *  Cilk library 1.0 are binary-incompatible with the same reducers compiled
+ *  with library 0.9, and therefore the optimization is suppressed when
+ *  compiling in 
+ *  ReducersMinMaxBinComp "binary compatibility mode". 
+ *  
+ *  @ingroup ReducersMinMax
+ */
+
+/** Test whether the ReducersMinMaxIsSet "is_set optimization" is
+ *  applicable.
+ *
+ *  The @ref do_is_set_optimization class is used to test whether the is_set
+ *  optimization should be applied for a particular reducer. It is instantiated
+ *  with a value type and a comparator, and defines a boolean constant, 
+ *  `value`. Then `%do_is_set_optimization<Type, Comp>::%value` can be used as
+ *  a boolean template parameter to control the specialization of another
+ *  class.
+ *
+ *  In ReducersMinMaxBinComp "binary compatibility mode", when the
+ *  `CILK_LIBRARY_0_9_REDUCER_MINMAX` macro is defined, `value` will always
+ *  be false.
+ *
+ *  @tparam Type   The value type for the reducer.
+ *  @tparam Compare The comparator type for the reducer.
+ *
+ *  @result The `value` data member will be `true` if @a Type is a numeric 
+ *          type, @a Compare is `std::less<Type>`, and 
+ *          `CILK_LIBRARY_0_9_REDUCER_MINMAX` is not defined.
+ *
+ *  @see ReducersMinMaxIsSet
+ *  @see @ref view_content
+ *
+ *  @ingroup ReducersMinMaxIsSet
+ */
+template <  typename Type, 
+            typename Compare >
+struct do_is_set_optimization 
+{ 
+    /// `True` if the is_set optimization should be applied to min/max reducers
+    /// with this value type and comparator; `false` otherwise.
+    static const bool value = false;
+};
+
+#ifndef CILK_LIBRARY_0_9_REDUCER_MINMAX
+/// @cond
+template <typename Type>
+struct do_is_set_optimization<Type, std::less<Type> > 
+{ 
+    /// True in the special case where optimization is possible.
+    static const bool value = std::numeric_limits<Type>::is_specialized;
+};
+/// @endcond
+#endif
+
+
+/** Get the identity value when using the ReducersMinMaxIsSet 
+ *  "is_set optimization".
+ *
+ *  This class defines a function which assigns the appropriate identity value
+ *  to a variable when the is_set optimization is applicable.
+ *
+ *  @tparam Type    The value type for the reducer.
+ *  @tparam Compare The comparator type for the reducer.
+ *  @tparam ForMax  `true` to get the identity value for a max reducer (i.e., 
+ *                  the smallest value of @a Type), `false` to get the identity
+ *                  value for a min reducer (i.e., the largest value of
+ *                  @a Type).
+ *
+ *  @result If @a Type and @a Compare qualify for the is_set optimization, the
+ *          `set_identity()' function will set its argument variable to the
+ *          smallest or largest value of @a Type, depending on @a ForMax.
+ *          Otherwise, `set_identity()` will be a no-op.
+ *
+ *  @see ReducersMinMaxIsSet
+ *
+ *  @ingroup ReducersMinMaxIsSet
+ *  @see @ref view_content
+ */
+template <  typename    Type, 
+            typename    Compare, 
+            bool        ForMax,
+            bool        = std::numeric_limits<Type>::is_specialized,
+            bool        = std::numeric_limits<Type>::has_infinity >
+struct identity_value {
+    /// Assign the identity value to the reference parameter.
+    static void set_identity(Type&) {}
+};
+
+/// @cond
+template <typename Type>
+struct identity_value<Type, std::less<Type>, true, true, true> {
+    /// Floating max identity is negative infinity.
+    static void set_identity(Type& id) 
+    { id = -std::numeric_limits<Type>::infinity(); }
+};
+
+template <typename Type>
+struct identity_value<Type, std::less<Type>, true, true, false> {
+    /// Integer max identity is minimum value of type.
+    static void set_identity(Type& id)
+    { id = std::numeric_limits<Type>::min(); }
+};
+
+template <typename Type>
+struct identity_value<Type, std::less<Type>, false, true, true> {
+    /// Floating min identity is positive infinity.
+    static void set_identity(Type& id)
+    { id = std::numeric_limits<Type>::infinity(); }
+};
+
+template <typename Type>
+struct identity_value<Type, std::less<Type>, false, true, false> {
+    /// Integer min identity is maximum value of type.
+    static void set_identity(Type& id)
+    { id = std::numeric_limits<Type>::max(); }
+};
+
+/// @endcond
+
+
+/** Adapter class to reverse the arguments of a predicate.
+ *
+ *  Observe that:
+ *
+ *      (x < y) == (y > x)
+ *      max(x, y) == (x < y) ? y : x
+ *      min(x, y) == (y < x) ? y : x == (x > y) ? y : x
+ *
+ *  More generally, if `c` is a predicate defining a `Strict Weak Ordering`, 
+ *  and  `c*(x, y) == c(y, x)`, then
+ *
+ *      max(x, y, c) == c(x, y) ? y : x
+ *      min(x, y, c) == c(y, x) ? y : x == c*(x, y) ? y : x == max(x, y, c*)
+ *
+ *  For any predicate `C` with argument type `T`, the template class 
+ *  `%reverse_predicate<C, T>` defines a predicate which is identical to `C`,
+ *  except that its arguments are reversed. Thus, for example, we could
+ *  implement `%op_min_view<Type, Compare>` as
+ *  `%op_max_view<Type, %reverse_predicate<Compare, Type> >`. 
+ *  (Actually, op_min_view and op_max_view are both implemented as subclasses 
+ *  of a common base class, view_base.)
+ *
+ *  @note   If `C` is an empty functor class, then `reverse_predicate(C)` will
+ *          also be an empty functor class.
+ *
+ *  @tparam Predicate   The predicate whose arguments are to be reversed.
+ *  @tparam Argument    @a Predicate’s argument type.
+ *
+ *  @ingroup ReducersMinMax
+ */
+template <typename Predicate,
+          typename Argument = typename Predicate::first_argument_type>
+class reverse_predicate : private binary_functor<Predicate>::type {
+    typedef typename binary_functor<Predicate>::type base;
+public:
+    /// Default constructor
+    reverse_predicate() : base() {}
+    /// Constructor with predicate object
+    reverse_predicate(const Predicate& p) : base(p) {} 
+    /// The reversed predicate operation
+    bool operator()(const Argument& x, const Argument& y) const
+        { return base::operator()(y, x); }
+};
+
+
+/** Class to represent the comparator for a min/max view class.
+ *
+ *  This class is intended to accomplish two objectives in the implementation 
+ *  of min/max views.
+ *
+ *  1.  To minimize data bloat, when we have a reducer with a non-stateless
+ *      comparator, we want to keep a single instance of the comparator object
+ *      in the monoid, and just call it from the views.
+ *  2.  In ReducersMinMaxBinComp "binary compatibility mode", views for
+ *      reducers with a stateless comparator must have the same content as in
+ *      Cilk library 0.9 — that is, they must contain only `value` and
+ *      `is_set` data members.
+ *
+ *  To achieve the first objective, we use the 
+ *  @ref internal::typed_indirect_binary_function class defined in
+ *  metaprogramming.h to wrap a pointer to the actual comparator. If no
+ *  pointer is needed because the actual comparator is stateless, the 
+ *  `typed_indirect_binary_function` class will be empty, too.
+ *
+ *  To achieve the second objective, we make the
+ *  `typed_indirect_binary_function` class a base class of the view rather than
+ *  a data member, so the “empty base class” rule will ensure no that no
+ *  additional space is allocated in the view unless it is needed.
+ *
+ *  We could simply use typed_indirect_binary_function as the base class of the
+ *  view, but this would mean writing comparisons as `(*this)(x, y)`, which is
+ *  just weird. So, instead, we comparator_base as a subclass of
+ *  typed_indirect_binary_function which provides function `compare()` 
+ *  as a synonym for `operator()`.
+ *
+ *  @tparam Type    The value type of the comparator class.
+ *  @tparam Compare A predicate class.
+ *
+ *  @see internal::typed_indirect_binary_function
+ *
+ *  @ingroup ReducersMinMax
+ */
+template <typename Type, typename Compare>
+class comparator_base : private typed_indirect_binary_function<Compare, Type, Type, bool>
+{
+    typedef typed_indirect_binary_function<Compare, Type, Type, bool> base;
+protected:
+    comparator_base(const Compare* f) : base(f) {}  ///< Constructor.
+    
+    /// Comparison function.
+    bool compare(const Type& a, const Type& b) const
+    {
+        return base::operator()(a, b); 
+    }
+    
+    /// Get the comparator pointer.
+    const Compare* compare_pointer() const { return base::pointer(); }
+};
+
+
+/** @defgroup ReducersMinMaxViewContent Content classes for min/max views
+ *
+ *  @ingroup ReducersMinMax
+ *
+ *  Minimum and maximum reducer view classes inherit from a “view content”
+ *  class. The content class defines the actual data members for the view,
+ *  and provides typedefs and member functions for accessing the data members
+ *  as needed to support the view functionality.
+ *
+ *  There are two content classes, which encapsulate the differences between
+ *  simple min/max reducers and min/max with index reducers:
+ *
+ *  -   view_content
+ *  -   index_view_content
+ *
+ *  @note   An obvious, and arguably simpler, encapsulation strategy would be
+ *          to just let the `Type` of a min/max view be an (index, value) pair
+ *          structure for min_index and max_index reducers. Then all views 
+ *          would just have a `Type` data member and an `is_set` data member,
+ *          and the comparator for min_index and max_index views could be
+ *          customized to consider only the value component of the (index,
+ *          value) `Type` pair. Unfortunately, this would break binary
+ *          compatibility with reducer_max_index and reducer_min_index in
+ *          Cilk library 0.9, because the memory layout of an (index, value)
+ *          pair followed by a `bool` is different from the memory layout of an
+ *          index data member followed by a value data member followed by a
+ *          `bool` data member. The content class is designed to exactly
+ *          replicate the layout of the views in library 0.9 reducers.
+ *
+ *  A content class `C`, and its objects `c`, must define the following:
+ *
+ *  Definition                          | Meaning
+ *  ------------------------------------|--------
+ *  `C::value_type`                     | A typedef for `Type` of the view. (A `std::pair<Index, Type>` for min_index and max_index views).
+ *  `C::comp_value_type`                | A typedef for the type of value compared by the view’s `compare()` function.
+ *  `C()`                               | Constructs the content with the identity value.
+ *  `C(const value_type&)`              | Constructs the content with a specified value.
+ *  `c.is_set()`                        | Returns true if the content has a known value.
+ *  `c.value()`                         | Returns the content’s value.
+ *  `c.set_value(const value_type&)`    | Sets the content’s value. (The value becomes known.)
+ *  `c.comp_value()`                    | Returns a const reference to the value or component of the value that is to be compared by the view’s comparator.
+ *  `C::comp_value(const value_type&)`  | Returns a const reference to a value or component of a value that is to be compared by the view’s comparator.
+ *
+ *  @see view_base
+ */
+
+/** Content class for op_min_view and op_max_view.
+ *
+ *  @tparam Type    The value type of the op_min_view or op_max_view.
+ *  @tparam Compare The comparator class specified for the op_min_view or 
+ *                  op_max_view. (_Not_ the derived comparator class actually
+ *                  used by the view_base. For example, the view_content of an
+ *                  `op_min_view<int>` will have `Compare = std::less<int>`, 
+ *                  but its comparator_base will have 
+ *                  `Compare = reverse_predicate< std::less<int> >`.)
+ *  @tparam ForMax  `true` if this is the content class for an op_max_view,
+ *                  `false` if it is for an op_min_view.
+ *
+ *  @note   The general implementation of view_content uses an `is_set` data
+ *          member. There is also a specialization which implements the 
+ *          ReducersMinMaxIsSet "is_set optimization". View classes that
+ *          inherit from view_content do not need to know anything about the
+ *          difference, though; the details are abstracted away in the 
+ *          view_content interface.
+ *
+ *  @see ReducersMinMaxViewContent
+ *
+ *  @ingroup ReducersMinMaxViewContent
+ *  @ingroup ReducersMinMax
+ */
+template < typename Type
+         , typename Compare
+         , bool     ForMax
+         , bool     = do_is_set_optimization<Type, Compare>::value
+         >
+class view_content {
+    Type    m_value;
+    bool    m_is_set;
+public:
+    /// The value type of the view.
+    typedef Type value_type;
+    
+    /// The type compared by the view’s `compare()` function (which is the same
+    /// as the value type for view_content).
+    typedef Type comp_value_type;
+    
+    /// Construct with the identity value.
+    view_content() : m_value(), m_is_set(false) {}
+    
+    /// Construct with a defined value.
+    view_content(const value_type& value) : m_value(value), m_is_set(true) {}
+    
+    /// Get the value.
+    value_type value() const { return m_value; }
+    
+    /// Set the value.
+    void set_value(const value_type& value) 
+    { 
+        m_value = value;
+        m_is_set = true;
+    }
+    
+    /// Get the comparison value (which is the same as the value for
+    /// view_content).
+    const comp_value_type& comp_value() const { return m_value; }
+
+    /// Given an arbitrary value, get the corresponding comparison value (which
+    /// is the same as the value for view_content).
+    static const comp_value_type& comp_value(const value_type& value) 
+    {
+        return value; 
+    }
+    
+    /// Get a const reference to value part of the value (which is the same as
+    /// the value for view_content).
+    const Type& get_reference() const { return m_value; }
+    
+    /// Get a const reference to the index part of the value (which is 
+    /// meaningless for non-index reducers, but required for view_base.
+    const Type& get_index_reference() const { return m_value; }
+    
+    /// Test if the value is defined.
+    bool is_set() const { return m_is_set; }
+};
+
+/// @cond
+
+/*  This is the specialization of the view_content class for cases where
+ *  `AssumeIsSet` is true (i.e., where the is_set optimization is applicable).
+ */
+template < typename Type
+         , typename Compare
+         , bool ForMax
+         >
+class view_content<Type, Compare, ForMax, true> {
+    typedef identity_value<Type, Compare, ForMax> Identity;
+    Type    m_value;
+public:
+    typedef Type value_type;
+    typedef Type comp_value_type;
+    
+    /// Construct with identity value.
+    view_content() { Identity::set_identity(m_value); }
+    
+    view_content(const value_type& value) : m_value(value) {}
+    
+    value_type value() const { return m_value; }
+    
+    void set_value(const value_type& value) 
+    { 
+        m_value = value;
+    }
+    
+    const comp_value_type& comp_value() const { return m_value; }
+
+    static const comp_value_type& comp_value(const value_type& value) 
+    {
+        return value; 
+    }
+    
+    const Type& get_reference() const { return m_value; }
+    
+    const Type& get_index_reference() const { return m_value; }
+    
+    /// Test if the value is defined.
+    bool is_set() const { return true; }
+};
+
+/// @endcond
+
+
+/** Content class for op_min_index_view and op_max_index_view.
+ *
+ *  @tparam Index   The index type of the op_min_index_view or
+                    op_max_index_view.
+ *  @tparam Type    The value type of the op_min_view or op_max_view. (_Not_ 
+ *                  the value type of the view, which will be
+ *                  `std::pair<Index, Type>`.)
+ *  @tparam Compare The comparator class specified for the op_min_index_view or 
+ *                  op_max_index_view. (_Not_ the derived comparator class
+ *                  actually used by the view_base. For example, the
+ *                  index_view_content of an `op_min_index_view<int>` will have
+ *                  `Compare = std::less<int>`, but its comparator_base will
+ *                  have `Compare = reverse_predicate< std::less<int> >`.)
+ *  @tparam ForMax  `true` if this is the content class for an
+ *                  op_max_index_view, `false` if it is for an
+ *                  op_min_index_view.
+ *
+ *  @see ReducersMinMaxViewContent
+ *
+ *  @ingroup ReducersMinMaxViewContent
+ *  @ingroup ReducersMinMax
+ */
+template < typename Index
+         , typename Type
+         , typename Compare
+         , bool ForMax
+         >
+class index_view_content {
+    typedef identity_value<Type, Compare, ForMax> Identity;
+
+    Index   m_index;
+    Type    m_value;
+    bool    m_is_set;
+public:
+    /// The value type of the view (which is an <index, value> pair for 
+    /// index_view_content).
+    typedef std::pair<Index, Type> value_type;
+    
+    /// The type compared by the view’s `compare()` function (which is the data 
+    /// value type for index_view_content).
+    typedef Type comp_value_type;
+    
+    /// Construct with the identity value.
+    index_view_content() : m_index(), m_value(), m_is_set(false) {}
+    
+    /// Construct with an index/value pair.
+    index_view_content(const value_type& value) : 
+        m_index(value.first), m_value(value.second), m_is_set(true) {}
+    
+    /// Construct with an index and a value.
+    index_view_content(const Index& index, const Type& value) : 
+        m_index(index), m_value(value), m_is_set(true) {}
+    
+    /// Construct with just an index.
+    index_view_content(const Index& index) : 
+        m_index(index), m_value(), m_is_set(false) {}
+    
+    /// Get the value.
+    value_type value() const { return value_type(m_index, m_value); }
+    
+    /// Set value.
+    void set_value(const value_type& value) 
+    { 
+        m_index = value.first; 
+        m_value = value.second;
+        m_is_set = true;
+    }
+    
+    /// Get the comparison value (which is the value component of the 
+    /// index/value pair for index_view_content).
+    const comp_value_type& comp_value() const { return m_value; }
+    
+    /// Given an arbitrary value (i.e., index/value pair), get the
+    /// corresponding comparison value (which is the value component of the
+    /// index/value pair for index_view_content).
+    static const comp_value_type& comp_value(const value_type& value) 
+        { return value.second; }
+    
+    /// Get a const reference to value part of the value.
+    const Type& get_reference() const { return m_value; }
+    
+    /// Get a const reference to the index part of the value.
+    const Index& get_index_reference() const { return m_index; }
+    
+    /// Test if the value is defined.
+    bool is_set() const { return m_is_set; }
+};
+
+
+template <typename View> class rhs_proxy;
+
+/** Create an rhs_proxy.
+ */
+template <typename View>
+inline rhs_proxy<View> 
+make_proxy(const typename View::value_type& value, const View& view);
+
+template <typename Content, typename Less, typename Compare> class view_base;
+
+
+/** Class to represent the right-hand side of 
+ *  `*reducer = {min|max}_of(*reducer, value)`.
+ *
+ *  The only assignment operator for a min/max view class takes a rhs_proxy as
+ *  its operand. This results in the syntactic restriction that the only
+ *  expressions that can be assigned to a min/max view are ones which generate
+ *  an rhs_proxy — that is, expressions of the form `max_of(view, value)` and
+ *  `min_of(view, value)`.
+ *
+ *  @warning
+ *  The lhs and rhs views in such an assignment must be the same; otherwise, 
+ *  the behavior will be undefined. (I.e., `*r1 = min_of(*r1, x)` is legal; 
+ *  `*r1 = min_of(*r2, x)` is illegal.)  This condition will be checked with a
+ *  runtime assertion when compiled in debug mode.
+ *
+ *  @tparam View    The view class (op_{min|max}[_index]_view) that this proxy
+ *                  was created from.
+ *
+ *  @see view_base
+ *
+ *  @ingroup ReducersMinMax
+ */
+template <typename View>
+class rhs_proxy {
+    typedef typename View::less_type                less_type;
+    typedef typename View::compare_type             compare_type;
+    typedef typename View::value_type               value_type;
+    typedef typename View::content_type             content_type;
+    typedef typename content_type::comp_value_type  comp_value_type;
+    
+    friend class view_base<content_type, less_type, compare_type>;
+    friend rhs_proxy make_proxy<View>(
+        const typename View::value_type& value, 
+        const View& view);
+    
+    typed_indirect_binary_function<
+        compare_type, comp_value_type, comp_value_type, bool>
+                                        m_comp;
+    const View*                         m_view;
+    value_type                          m_value;
+
+    rhs_proxy& operator=(const rhs_proxy&); // Disable assignment operator
+    rhs_proxy();                            // Disable default constructor
+    
+    // Constructor (called from view_base::make_proxy).
+    rhs_proxy(const View* view, 
+              const value_type& value,
+              const compare_type* compare) : 
+        m_view(view), m_value(value), m_comp(compare) {}
+        
+    // Check matching view, then return value (called from view_base::assign).
+    value_type value(const typename View::base* view) const
+    { 
+        __CILKRTS_ASSERT(view == m_view); 
+        return m_value; 
+    }
+
+public:
+
+    /** Support max_of(max_of(view, value), value) and the like.
+     */
+    rhs_proxy calc(const value_type& x) const
+    {
+        return rhs_proxy(
+            m_view, 
+            m_comp( content_type::comp_value(m_value),     
+                    content_type::comp_value(x)
+                  ) ? x : m_value,
+            m_comp.pointer());
+    }
+};
+    
+    
+template <typename View>
+inline rhs_proxy<View> 
+make_proxy(const typename View::value_type& value, const View& view)
+{
+    return rhs_proxy<View>(&view, value, view.compare_pointer());
+}
+
+//@}
+
+/** Base class for min and max view classes.
+ *
+ *  This class accumulates the minimum or maximum of a set of values which have
+ *  occurred as arguments to the `calc()` function, as determined by a
+ *  comparator. The accumulated value will be the first `calc()` argument value
+ *  `x` such that `compare(x, y)` is false for every `calc()` argument value
+ *  `y`.
+ *
+ *  If the comparator is `std::less`, then the accumulated value is the first
+ *  argument value which is not less than any other argument value, i.e., the
+ *  maximum. Similarly, if the comparator is `reverse_predicate<std::less>`,
+ *  which is equivalent to `std::greater`, then the accumulated value is the
+ *  first argument value which is not greater than any other argument value,
+ *  i.e., the minimum.
+ *  
+ *  @note   This class provides the definitions that are required for a class
+ *          that will be used as the parameter of a 
+ *          min_max_internal::monoid_base specialization. 
+ *
+ *  @tparam Content     A content class that provides the value types and data
+ *                      members for the view.
+ *  @tparam Less        A “less than” binary predicate that defines the min or
+ *                      max function.
+ *  @tparam Compare     A binary predicate to be used to compare the values.
+ *                      (The same as @a Less for max reducers; its reversal for
+ *                      min reducers.)
+ *
+ *  @see ReducersMinMaxViewContent
+ *  @see op_max_view
+ *  @see op_min_view
+ *  @see op_max_index_view
+ *  @see op_min_index_view
+ *  @see monoid_base
+ *
+ *  @ingroup ReducersMinMax
+ */
+template <typename Content, typename Less, typename Compare>
+class view_base : 
+    // comparator_base comes first to ensure that it will get empty base class
+    // treatment
+    private comparator_base<typename Content::comp_value_type, Compare>, 
+    private Content
+{
+    typedef comparator_base<typename Content::comp_value_type, Compare> base;
+    using base::compare;
+    using Content::value;
+    using Content::set_value;
+    using Content::comp_value;
+    typedef Content content_type;
+    
+    template <typename View> friend class rhs_proxy;
+    template <typename View>
+    friend rhs_proxy<View> make_proxy(const typename View::value_type& value, const View& view);
+    
+public:
+    
+    /** @name Monoid support.
+     */
+    //@{
+    
+    /** Value type. Required by @ref monoid_with_view.
+     */
+    typedef typename Content::value_type    value_type;
+    
+    /** The type of the comparator specified by the user, that defines the 
+     *  ordering on @a Type. Required by min_max::monoid_base.
+     */
+    typedef Less                            less_type;
+    
+    /** The type of the comparator actually used by the view. Required by 
+     *  min_max::monoid_base. (This is the same as the @ref less_type for a 
+     *  max reducer, or `reverse_predicate<less_type>` for a min reducer.)
+     */
+    typedef Compare                         compare_type;
+
+    /** Reduce operation. Required by @ref monoid_with_view.
+     */
+    void reduce(view_base* other)
+    {
+        if (    other->is_set() &&
+                (   !this->is_set() || 
+                    compare(this->comp_value(), other->comp_value()) ) )
+        {
+            this->set_value(other->value());
+        }
+    }
+    
+    //@}
+    
+    /** Default constructor. Initializes to identity value.
+     */
+    explicit view_base(const compare_type* compare) : 
+        base(compare), Content() {}
+    
+    /** Value constructor.
+     */
+    template <typename T1>
+    view_base(const T1& x1, const compare_type* compare) : 
+        base(compare), Content(x1) {}
+
+    /** Value constructor.
+     */
+    template <typename T1, typename T2>
+    view_base(const T1& x1, const T2& x2, const compare_type* compare) : 
+        base(compare), Content(x1, x2) {}
+
+
+    /** Move-in constructor.
+     */
+    explicit view_base(move_in_wrapper<value_type> w, const compare_type* compare) :
+        base(compare), Content(w.value()) {}
+    
+    /** @name Reducer support.
+     */
+    //@{
+    
+    void                view_move_in(value_type& v)         { set_value(v); }
+    void                view_move_out(value_type& v)        { v = value(); }
+    void                view_set_value(const value_type& v) { set_value(v); }
+    value_type          view_get_value() const              { return value(); }
+    //                  view_get_reference()                NOT SUPPORTED
+    
+    //@}
+    
+    /** Is the value defined?
+     */
+    using Content::is_set;
+    
+    /** Reference to contained value data member.
+     *  @deprecated For legacy reducers only.
+     */
+    using Content::get_reference;
+    
+    /** Reference to contained index data member.
+     *  (Meaningless for non-index reducers.)
+     *  @deprecated For legacy reducers only.
+     */
+    using Content::get_index_reference;
+    
+protected:
+
+    /** Update the min/max value.
+     */
+    void calc(const value_type& x)
+    {
+        if (!is_set() || compare(comp_value(), comp_value(x))) set_value(x);
+    }
+    
+    /** Assign the result of a `{min|max}_of(view, value)` expression to the 
+     *  view.
+     *
+     *  @see rhs_proxy
+     */
+    template <typename View>
+    void assign(const rhs_proxy<View>& rhs)
+    {
+        calc(rhs.value(this));
+    }
+    
+};
+
+
+/** Base class for min and max monoid classes.
+ *
+ *  The unique characteristic of minimum and maximum reducers is that they 
+ *  incorporate a comparator functor that defines what “minimum” or “maximum”
+ *  means. The monoid for a reducer contains the comparator that will be used
+ *  for the reduction. If the comparator is a function or a class with state,
+ *  then each view will have a pointer to the comparator.
+ *
+ *  This means that the `construct()` functions first construct the monoid
+ *  (possibly with an explicit comparator argument), and then construct the 
+ *  view with a pointer to the monoid’s comparator.
+ *
+ *  @tparam View    The view class.
+ *  @tparam Align   If true, reducers instantiated on this monoid will be
+ *                  aligned. By default, library reducers (unlike legacy
+ *                  library reducer _wrappers_) are unaligned.
+ *
+ *  @see view_base
+ *
+ *  @ingroup ReducersMinMax
+ */
+template <typename View, bool Align = false>
+class monoid_base : public monoid_with_view<View, Align>
+{
+    typedef typename View::compare_type compare_type;
+    typedef typename View::less_type    less_type;
+    const compare_type                  m_compare;
+
+    const compare_type* compare_pointer() const { return &m_compare; }
+    
+    using cilk::monoid_base<typename View::value_type, View>::provisional;
+    
+public:
+
+    /** Default constructor uses default comparator.
+     */
+    monoid_base() : m_compare() {}
+
+    /** Constructor.
+     *
+     *  @param  compare The comparator to use.
+     */
+    monoid_base(const compare_type& compare) : m_compare(compare) {}
+
+    /** Create an identity view.
+     *
+     *  List view identity constructors take the list allocator as an argument.
+     *
+     *  @param v    The address of the uninitialized memory in which the view 
+     *  will be constructed.
+     */
+    void identity(View *v) const { ::new((void*) v) View(compare_pointer()); }
+    
+    /** @name construct functions
+     *
+     *  Min/max monoid `construct()` functions optionally take one or two value
+     *  arguments, a @ref move_in argument, and/or a comparator argument.
+     */
+    //@{
+    
+    template <typename Monoid>
+    static void construct(Monoid* monoid, View* view)
+        { provisional( new ((void*)monoid) Monoid() ).confirm_if( 
+            new ((void*)view) View(monoid->compare_pointer()) ); }
+
+    template <typename Monoid, typename T1>
+    static void construct(Monoid* monoid, View* view, const T1& x1)
+        { provisional( new ((void*)monoid) Monoid() ).confirm_if( 
+            new ((void*)view) View(x1, monoid->compare_pointer()) ); }
+
+    template <typename Monoid, typename T1, typename T2>
+    static void construct(Monoid* monoid, View* view, const T1& x1, const T2& x2)
+        { provisional( new ((void*)monoid) Monoid() ).confirm_if( 
+            new ((void*)view) View(x1, x2, monoid->compare_pointer()) ); }
+
+    template <typename Monoid>
+    static void construct(Monoid* monoid, View* view, const less_type& compare)
+        { provisional( new ((void*)monoid) Monoid(compare) ).confirm_if( 
+            new ((void*)view) View(monoid->compare_pointer()) ); }
+
+    template <typename Monoid, typename T1>
+    static void construct(Monoid* monoid, View* view, const T1& x1, const less_type& compare)
+        { provisional( new ((void*)monoid) Monoid(compare) ).confirm_if( 
+            new ((void*)view) View(x1, monoid->compare_pointer()) ); }
+
+    template <typename Monoid, typename T1, typename T2>
+    static void construct(Monoid* monoid, View* view, const T1& x1, const T2& x2, const less_type& compare)
+        { provisional( new ((void*)monoid) Monoid(compare) ).confirm_if( 
+            new ((void*)view) View(x1, x2, monoid->compare_pointer()) ); }
+
+    //@}
+};
+
+} //namespace min_max_internal
+
+
+/** @defgroup ReducersMinMaxMaxValue Maximum reducers (value only)
+ *
+ *  These reducers will find the largest value from a set of values.
+ *
+ *  @ingroup ReducersMinMax
+ */
+//@{
+
+/** The maximum reducer view class.
+ *
+ *  This is the view class for reducers created with 
+ *  `cilk::reducer< cilk::op_max<Type, Compare> >`. It accumulates the maximum,
+ *  as determined by a comparator, of a set of values which have occurred as
+ *  arguments to the `calc_max()` function. The accumulated value will be the
+ *  first argument `x` such that `compare(x, y)` is false for every argument
+ *  `y`.
+ *
+ *  If the comparator is `std::less`, then the accumulated value is the first
+ *  argument value which is not less than any other argument value, i.e., the
+ *  maximum.
+ *
+ *  @note   The reducer “dereference” operation (`reducer::operator *()`) 
+ *          yields a reference to the view. Thus, for example, the view class’s
+ *          `calc_max()` function would be used in an expression like
+ *          `r->calc_max(a)` where `r` is an op_max reducer variable.
+ *
+ *  @tparam Type    The type of the values compared by the reducer. This will
+ *                  be the value type of a monoid_with_view that is 
+ *                  instantiated with this view.
+ *  @tparam Compare A `Strict Weak Ordering` whose argument type is @a Type. It
+ *                  defines the “less than” relation used to compute the
+ *                  maximum.
+ *
+ *  @see ReducersMinMax
+ *  @see op_max
+ */
+template <typename Type, typename Compare>
+class op_max_view : public min_max_internal::view_base<
+    min_max_internal::view_content<Type, Compare, true>, 
+    Compare,
+    Compare>
+{
+    typedef min_max_internal::view_base<
+        min_max_internal::view_content<Type, Compare, true>, 
+        Compare,
+        Compare> base;
+    using base::calc;
+    using base::assign;
+    friend class min_max_internal::rhs_proxy<op_max_view>;
+    
+public:
+
+    /** @name Constructors.
+     *
+     *  All op_max_view constructors simply pass their arguments on to the 
+     *  @ref view_base base class.
+     */
+    //@{
+    
+    op_max_view() : base() {}
+    
+    template <typename T1>
+    op_max_view(const T1& x1) : base(x1) {}
+    
+    template <typename T1, typename T2>
+    op_max_view(const T1& x1, const T2& x2) : base(x1, x2) {}
+    
+    //@}    
+
+    /** @name View modifier operations.
+     */
+    //@{
+    
+    /** Maximize with a value.
+     *
+     *  If @a x is greater than the current value of the view (as defined by 
+     *  the reducer’s comparator), or if the view was created without an 
+     *  initial value and its value has never been updated (with `calc_max()` 
+     *  or `= max_of()`), then the value of the view is set to @a x.
+     *
+     *  @param  x   The value to maximize the view’s value with.
+     *
+     *  @return     A reference to the view. (Allows chaining
+     *              `view.comp_max(a).comp_max(b)…`.)
+     */
+    op_max_view& calc_max(const Type& x) { calc(x); return *this; }
+
+    /** Assign the result of a `max_of(view, value)` expression to the view.
+     *
+     *  @param  rhs An rhs_proxy value created by a `max_of(view, value)`
+     *              expression.
+     *
+     *  @return     A reference to the view.
+     *
+     *  @see min_max_internal::view_base::rhs_proxy
+     */
+    op_max_view& operator=(const min_max_internal::rhs_proxy<op_max_view>& rhs) 
+        { assign(rhs); return *this; }
+    
+    //@}
+};
+
+
+/** Compute the maximum of the value in an op_max_view and another value.
+ *
+ *  The result of this computation can only be assigned back to the original 
+ *  view or used in another max_of() call. For example,
+ *
+ *      *reducer = max_of(*reducer, x);
+ *      *reducer = max_of(x, *reducer);
+ *
+ *  @see min_max_internal::rhs_proxy
+ */
+template <typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_view<Type, Compare> >
+max_of(const op_max_view<Type, Compare>& view, const Type& value)
+{
+    return min_max_internal::make_proxy(value, view);
+}
+
+/// @copydoc max_of(const op_max_view<Type, Compare>&, const Type&)
+template <typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_view<Type, Compare> >
+max_of(const Type& value, const op_max_view<Type, Compare>& view)
+{
+    return min_max_internal::make_proxy(value, view);
+}
+
+/** Nested maximum computation.
+ *
+ *  Compute the maximum of the result of a max_of() call and another value.
+ *
+ *  The result of this computation can only be assigned back to the original
+ *  view or wrapper, or used in another max_of() call. For example,
+ *
+ *      *reducer = max_of(x, max_of(y, *reducer));
+ *      wrapper = max_of(max_of(wrapper, x), y);
+ *
+ *  @see min_max_internal::rhs_proxy
+ */
+template <typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_view<Type, Compare> >
+max_of(const min_max_internal::rhs_proxy< op_max_view<Type, Compare> >& proxy, 
+       const Type& value)
+{
+    return proxy.calc(value);
+}
+
+/// @copydoc max_of(const min_max_internal::rhs_proxy< op_max_view<Type, Compare> >&, const Type&)
+template <typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_view<Type, Compare> >
+max_of(const Type& value, 
+       const min_max_internal::rhs_proxy< op_max_view<Type, Compare> >& proxy)
+{
+    return proxy.calc(value);
+}
+
+
+/** Monoid class for maximum reductions. Instantiate the cilk::reducer template
+ *  class with an op_max monoid to create a maximum reducer class. For example,
+ *  to compute the maximum of a set of `int` values:
+ *
+ *      cilk::reducer< cilk::op_max<int> > r;
+ *
+ *  @see ReducersMinMax
+ *  @see op_max_view
+ */
+template <typename Type, typename Compare=std::less<Type>, bool Align = false>
+class op_max : 
+    public min_max_internal::monoid_base<op_max_view<Type, Compare>, Align> 
+{
+    typedef min_max_internal::monoid_base<op_max_view<Type, Compare>, Align>
+            base;
+public:
+    /// Construct with default comparator.
+    op_max() {}
+    /// Construct with specified comparator.
+    op_max(const Compare& compare) : base(compare) {}
+};
+
+//@}
+
+
+/** @defgroup ReducersMinMaxMinValue Minimum reducers (value only)
+ *
+ *  These reducers will find the smallest value from a set of values.
+ *
+ *  @ingroup ReducersMinMax
+ */
+//@{
+
+/** The minimum reducer view class.
+ *
+ *  This is the view class for reducers created with 
+ *  `cilk::reducer< cilk::op_min<Type, Compare> >`. It accumulates the minimum,
+ *  as determined by a comparator, of a set of values which have occurred as
+ *  arguments to the `calc_min()` function. The accumulated value will be the
+ *  first argument `x` such that `compare(y, x)` is false for every argument
+ *  `y`.
+ *
+ *  If the comparator is `std::less`, then the accumulated value is the first
+ *  argument value which no other argument value is less than, i.e., the
+ *  minimum.
+ *
+ *  @note   The reducer “dereference” operation (`reducer::operator *()`) 
+ *          yields a reference to the view. Thus, for example, the view class’s
+ *          `calc_min()` function would be used in an expression like
+ *          `r->calc_min(a)` where `r` is an op_min reducer variable.
+ *
+ *  @tparam Type    The type of the values compared by the reducer. This will 
+ *                  be the value type of a monoid_with_view that is 
+ *                  instantiated with this view.
+ *  @tparam Compare A `Strict Weak Ordering` whose argument type is @a Type. It 
+ *                  defines the “less than” relation used to compute the
+ *                  minimum.
+ *
+ *  @see ReducersMinMax
+ *  @see op_min
+ */
+template <typename Type, typename Compare>
+class op_min_view : public min_max_internal::view_base<
+    min_max_internal::view_content<Type, Compare, false>, 
+    Compare,
+    min_max_internal::reverse_predicate<Compare, Type> >
+{
+    typedef min_max_internal::view_base<
+        min_max_internal::view_content<Type, Compare, false>, 
+        Compare,
+        min_max_internal::reverse_predicate<Compare, Type> > base;
+    using base::calc;
+    using base::assign;
+    friend class min_max_internal::rhs_proxy<op_min_view>;
+
+public:
+    /** @name Constructors.
+     *
+     *  All op_min_view constructors simply pass their arguments on to the 
+     *  @ref view_base base class.
+     */
+    //@{
+    
+    op_min_view() : base() {}
+    
+    template <typename T1>
+    op_min_view(const T1& x1) : base(x1) {}
+    
+    template <typename T1, typename T2>
+    op_min_view(const T1& x1, const T2& x2) : base(x1, x2) {}
+    
+    //@}    
+
+    /** @name View modifier operations.
+     */
+    //@{
+    
+    /** Minimize with a value.
+     *
+     *  If @a x is less than the current value of the view (as defined by the
+     *  reducer’s comparator), or if the view was created without an initial
+     *  value and its value has never been updated (with `calc_min()` or
+     *  `= min_of()`), then the value of the view is set to @a x.
+     *
+     *  @param  x   The value to minimize the view’s value with.
+     *
+     *  @return     A reference to the view. (Allows chaining
+     *              `view.comp_min(a).comp_min(b)…`.)
+     */
+    op_min_view& calc_min(const Type& x) { calc(x); return *this; }
+
+    /** Assign the result of a `min_of(view, value)` expression to the view.
+     *
+     *  @param  rhs An rhs_proxy value created by a `min_of(view, value)`
+     *              expression.
+     *
+     *  @return     A reference to the view.
+     *
+     *  @see min_max_internal::view_base::rhs_proxy
+     */
+    op_min_view& operator=(const min_max_internal::rhs_proxy<op_min_view>& rhs) 
+        { assign(rhs); return *this; }
+};
+
+
+/** Compute the minimum of the value in a view and another value.
+ *
+ *  The result of this computation can only be assigned back to the original
+ *  view or used in another min_of() call. For example,
+ *
+ *      *reducer = min_of(*reducer, x);
+ *      *reducer = min_of(x, *reducer);
+ *
+ *  @see min_max_internal::view_base::rhs_proxy
+ */
+template <typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_view<Type, Compare> >
+min_of(const op_min_view<Type, Compare>& view, const Type& value)
+{
+    return min_max_internal::make_proxy(value, view);
+}
+
+/// @copydoc min_of(const op_min_view<Type, Compare>&, const Type&)
+template <typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_view<Type, Compare> >
+min_of(const Type& value, const op_min_view<Type, Compare>& view)
+{
+    return min_max_internal::make_proxy(value, view);
+}
+
+/** Nested minimum computation.
+ *
+ *  Compute the minimum of the result of a min_of() call and another value.
+ *
+ *  The result of this computation can only be assigned back to the original
+ *  view or wrapper, or used in another min_of() call. For example,
+ *
+ *      *reducer = min_of(x, min_of(y, *reducer));
+ *      wrapper = min_of(min_of(wrapper, x), y);
+ *
+ *  @see min_max_internal::rhs_proxy
+ */
+template <typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_view<Type, Compare> >
+min_of(const min_max_internal::rhs_proxy< op_min_view<Type, Compare> >& proxy, 
+       const Type& value)
+{
+    return proxy.calc(value);
+}
+
+/// @copydoc min_of(const min_max_internal::rhs_proxy< op_min_view<Type, Compare> >&, const Type&)
+template <typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_view<Type, Compare> >
+min_of(const Type& value, 
+       const min_max_internal::rhs_proxy< op_min_view<Type, Compare> >& proxy)
+{
+    return proxy.calc(value);
+}
+
+
+/** Monoid class for minimum reductions. Instantiate the cilk::reducer template
+ *  class with an op_min monoid to create a minimum reducer class. For example,
+ *  to compute the minimum of a set of `int` values:
+ *
+ *      cilk::reducer< cilk::op_min<int> > r;
+ *
+ *  @see ReducersMinMax
+ *  @see op_min_view
+ */
+template <typename Type, typename Compare=std::less<Type>, bool Align = false>
+class op_min : public min_max_internal::monoid_base<op_min_view<Type, Compare>, Align> {
+    typedef min_max_internal::monoid_base<op_min_view<Type, Compare>, Align> base;
+public:
+    /// Construct with default comparator.
+    op_min() {}
+    /// Construct with specified comparator.
+    op_min(const Compare& compare) : base(compare) {}
+};
+
+//@}
+
+
+/** @defgroup ReducersMinMaxMaxIndex Maximum reducers (value and index)
+ *
+ *  These reducers will find the largest value from a set of values, and its
+ *  index in the set.
+ *
+ *  @ingroup ReducersMinMax
+ */
+//@{
+
+/** The maximum index reducer view class.
+ *
+ *  This is the view class for reducers created with 
+ *  `cilk::reducer< cilk::op_max_index<Index, Type, Compare> >`. It accumulates
+ *  the maximum, as determined by a comparator, of a set of values which have
+ *  occurred as arguments to the `calc_max()` function, and records the index
+ *  of the maximum value. The accumulated value will be the first argument `x`
+ *  such that `compare(x, y)` is false for every argument `y`.
+ *
+ *  If the comparator is `std::less`, then the accumulated value is the first
+ *  argument value which is not less than any other argument value, i.e., the
+ *  maximum.
+ *
+ *  @note   The reducer “dereference” operation (`reducer::operator *()`) 
+ *          yields a reference to the view. Thus, for example, the view class’s
+ *          `calc_max()` function would be used in an expression like
+ *          `r->calc_max(i, a)`where `r` is an op_max_index reducer
+ *          variable.
+ *
+ *  @note   The word “index” suggests an integer index into an array, but there
+ *          is no restriction on the index type or how it should be used. In
+ *          general, it may be convenient to use it for any kind of key that 
+ *          can be used to locate the maximum value in the collection that it
+ *          came from — for example:
+ *              -   An index into an array.
+ *              -   A key into an STL map.
+ *              -   An iterator into any STL container.
+ *
+ *  @note   A max_index reducer is essentially a max reducer whose value type 
+ *          is a `std::pair<Index, Type>`. This fact is camouflaged in the view
+ *          `calc_max` function, the global `max_of` functions, and the reducer
+ *          value constructor, which can all take an index argument and a value
+ *          argument as an alternative to a single `std::pair` argument.
+ *          However, the reducer `set_value()`, `get_value()`, `move_in()`, and
+ *          `move_out()` functions work only with pairs, not with individual 
+ *          value and/or index arguments.
+ *
+ *  @tparam Index   The type of the indices associated with the values.
+ *  @tparam Type    The type of the values compared by the reducer. This will 
+ *                  be the value type of a monoid_with_view that is 
+ *                  instantiated with this view.
+ *  @tparam Compare Used to compare the values. It must be a binary predicate.
+ *                  If it is omitted, then the view computes the conventional
+ *                  arithmetic maximum.
+ *
+ *  @see ReducersMinMax
+ *  @see op_max_index
+ */
+template <typename Index, typename Type, typename Compare>
+class op_max_index_view : public min_max_internal::view_base<
+    min_max_internal::index_view_content<Index, Type, Compare, true>,
+    Compare,
+    Compare>
+{
+    typedef min_max_internal::view_base<
+        min_max_internal::index_view_content<Index, Type, Compare, true>,
+        Compare,
+        Compare> base;
+    using base::calc;
+    using base::assign;
+    typedef std::pair<Index, Type> pair_type;
+    friend class min_max_internal::rhs_proxy<op_max_index_view>;
+
+public:
+    /** @name Constructors.
+     *
+     *  All op_max_index_view constructors simply pass their arguments on to the 
+     *  @ref view_base base class, except for the `(index, value [, compare])`
+     *  constructors, which create a `std::pair` containing the index and value.
+     */
+    //@{
+    
+    op_max_index_view() : base() {}
+    
+    template <typename T1>
+    op_max_index_view(const T1& x1) : base(x1) {}
+    
+    template <typename T1, typename T2>
+    op_max_index_view(const T1& x1, const T2& x2) : base(x1, x2) {}
+    
+    template <typename T1, typename T2, typename T3>
+    op_max_index_view(const T1& x1, const T2& x2, const T3& x3) : base(x1, x2, x3) {}
+    
+    op_max_index_view(const Index& i, const Type& v) : base(pair_type(i, v)) {}
+    
+    op_max_index_view(const Index& i, const Type& v, const typename base::compare_type* c) : 
+        base(pair_type(i, v), c) {}
+    
+    //@}    
+
+    /** Maximize with a value and index.
+     *
+     *  If @a x is greater than the current value of the view (as defined by 
+     *  the reducer’s comparator), or if the view was created without an 
+     *  initial value and its value has never been updated (with `calc_max()` 
+     *  or `= max_of()`), then the value of the view is set to @a x, and the
+     *  index is set to @a i..
+     *
+     *  @param  i   The index of the value @a x.
+     *  @param  x   The value to maximize the view’s value with.
+     *
+     *  @return     A reference to the view. (Allows 
+     *              `view.comp_max(i, a).comp_max(j, b)…`.)
+     */
+    op_max_index_view& calc_max(const Index& i, const Type& x) 
+        { calc(pair_type(i, x)); return *this; }
+
+    /** Maximize with an index/value pair.
+     *
+     *  If @a pair.second is greater than the current value of the view (as
+     *  defined by the reducer’s comparator), or if the view was created 
+     *  without an initial value and its value has never been updated (with
+     *  `calc_max()` or `= max_of()`), then the value of the view is set to
+     *  @a pair.second, and the index is set to @a pair.first.
+     *
+     *  @param  pair    A pair containing a value to maximize the view’s value
+     *                  with and its associated index.
+     *
+     *  @return         A reference to the view. (Allows
+     *                  `view.comp_max(p1).comp_max(p2)…`.)
+     */
+    op_max_index_view& calc_max(const pair_type& pair) 
+        { calc(pair); return *this; }
+
+    /** Assign the result of a `max_of(view, index, value)` expression to the 
+     *  view.
+     *
+     *  @param  rhs An rhs_proxy value created by a `max_of(view, index, value)`
+     *              expression.
+     *
+     *  @return     A reference to the view.
+     *
+     *  @see min_max_internal::view_base::rhs_proxy
+     */
+    op_max_index_view& operator=(const min_max_internal::rhs_proxy<op_max_index_view>& rhs) 
+        { assign(rhs); return *this; }
+};
+
+
+/** Compute the maximum of the value in a view and another value.
+ *
+ *  The result of this computation can only be assigned back to the original
+ *  view or used in another max_of() call. For example,
+ *
+ *      *reducer = max_of(*reducer, i, x);
+ *      *reducer = max_of(i, x, *reducer);
+ *
+ *  @see min_max_internal::rhs_proxy
+ */
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >
+max_of(const op_max_index_view<Index, Type, Compare>& view,
+       const Index& index, const Type& value)
+{
+    return min_max_internal::make_proxy(std::pair<Index, Type>(index, value), view);
+}
+
+/// @copydoc max_of(const op_max_index_view<Index, Type, Compare>&, const Index&, const Type&)
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >
+max_of(const Index& index, const Type& value,
+       const op_max_index_view<Index, Type, Compare>& view)
+{
+    return min_max_internal::make_proxy(std::pair<Index, Type>(index, value), view);
+}
+
+/// @copydoc max_of(const op_max_index_view<Index, Type, Compare>&, const Index&, const Type&)
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >
+max_of(const op_max_index_view<Index, Type, Compare>& view,
+       const std::pair<Index, Type>& pair)
+{
+    return min_max_internal::make_proxy(pair, view);
+}
+
+/// @copydoc max_of(const op_max_index_view<Index, Type, Compare>&, const Index&, const Type&)
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >
+max_of(const std::pair<Index, Type>& pair,
+       const op_max_index_view<Index, Type, Compare>& view)
+{
+    return min_max_internal::make_proxy(pair, view);
+}
+
+/** Nested computation of the maximum of the value in a view and other values.
+ *
+ *  Compute the maximum of the result of a max_of() call and another value.
+ *
+ *  The result of this computation can only be assigned back to the original
+ *  view or used in another max_of() call. For example,
+ *
+ *      *reducer = max_of(x, max_of(y, *reducer));
+ *      *reducer = max_of(max_of(*reducer, x), y);
+ *
+ *  @see min_max_internal::rhs_proxy
+ */
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >
+max_of(const min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >& proxy,
+       const Index& index, const Type& value)
+{
+    return proxy.calc(std::pair<Index, Type>(index, value));
+}
+
+/// @copydoc max_of(const min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >&, const Index&, const Type&)
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >
+max_of(const Index& index, const Type& value,
+       const min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >& proxy)
+{
+    return proxy.calc(std::pair<Index, Type>(index, value));
+}
+
+/// @copydoc max_of(const min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >&, const Index&, const Type&)
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >
+max_of(const min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >& proxy,
+       const std::pair<Index, Type>& pair)
+{
+    return proxy.calc(pair);
+}
+
+/// @copydoc max_of(const min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >&, const Index&, const Type&)
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >
+max_of(const std::pair<Index, Type>& pair,
+       const min_max_internal::rhs_proxy< op_max_index_view<Index, Type, Compare> >& proxy)
+{
+    return proxy.calc(pair);
+}
+
+
+/** Monoid class for maximum reductions with index. Instantiate the
+ *  cilk::reducer template class with an op_max_index monoid to create a
+ *  max_index reducer class. For example, to compute the maximum of an array of
+ *  `double` values and the array index of the max value:
+ *
+ *      cilk::reducer< cilk::op_max_index<unsigned, double> > r;
+ *
+ *  @see ReducersMinMax
+ *  @see op_max_index_view
+ */
+template < typename Index
+         , typename Type
+         , typename Compare=std::less<Type>
+         , bool     Align = false
+         >
+class op_max_index : public min_max_internal::monoid_base<op_max_index_view<Index, Type, Compare>, Align> 
+{
+    typedef min_max_internal::monoid_base<
+        op_max_index_view<Index, Type, Compare>, Align> base;
+public:
+    /// Construct with default comparator.
+    op_max_index() {}
+    /// Construct with specified comparator.
+    op_max_index(const Compare& compare) : base(compare) {}
+};
+
+//@}
+
+
+
+/** @defgroup ReducersMinMaxMinIndex Minimum reducers (value and index)
+ *
+ *  These reducers will find the smallest value from a set of values, and its
+ *  index in the set.
+ *
+ *  @ingroup ReducersMinMax
+ */
+//@{
+
+/** The minimum index reducer view class.
+ *
+ *  This is the view class for reducers created with 
+ *  `cilk::reducer<cilk::op_min_index<Index, Type, Compare> >`. It accumulates
+ *  the minimum, as determined by a comparator, of a set of values which have
+ *  occurred as arguments to the `calc_min()` function, and records the index
+ *  of the minimum value. The accumulated value will be the first argument `x`
+ *  such that `compare(y, x)` is false for every argument `y`.
+ *
+ *  If the comparator is `std::less`, then the accumulated value is the first
+ *  argument value which no other argument value is less than, i.e., the
+ *  minimum.
+ *
+ *  @note   The reducer “dereference” operation (`reducer::operator *()`) 
+ *          yields a reference to the view. Thus, for example, the view class’s
+ *          `calc_min()` function would be
+ *          used in an expression like `r->calc_min(i, a)`where `r` is an
+ *          op_min_index reducer variable.
+ *
+ *  @note   The word “index” suggests an integer index into an array, but there
+ *          is no restriction on the index type or how it should be used. In
+ *          general, it may be convenient to use it for any kind of key that 
+ *          can be used to locate the minimum value in the collection that it
+ *          came from — for example:
+ *              -   An index into an array.
+ *              -   A key into an STL map.
+ *              -   An iterator into any STL container.
+ *
+ *  @note   A min_index reducer is essentially a min reducer whose value type 
+ *          is a `std::pair<Index, Type>`. This fact is camouflaged in the view
+ *          `calc_min` function, the global `min_of` functions, and the reducer
+ *          value constructor, which can all take an index argument and a value
+ *          argument as an alternative to a single `std::pair` argument.
+ *          However, the reducer `set_value()`, `get_value()`, `move_in()`, and
+ *          `move_out()` functions work only with pairs, not with individual
+ *          value and/or index arguments.
+ *
+ *  @tparam Index   The type of the indices associated with the values.
+ *  @tparam Type    The type of the values compared by the reducer. This will 
+ *                  be the value type of a monoid_with_view that is 
+ *                  instantiated with this view.
+ *  @tparam Compare Used to compare the values. It must be a binary predicate.
+ *                  If it is omitted, then the view computes the conventional
+ *                  arithmetic minimum.
+ *
+ *  @see ReducersMinMax
+ *  @see op_min_index
+ */
+template <typename Index, typename Type, typename Compare>
+class op_min_index_view : public min_max_internal::view_base<
+    min_max_internal::index_view_content<Index, Type, Compare, false>,
+    Compare,
+    min_max_internal::reverse_predicate<Compare, Type> >
+{
+    typedef min_max_internal::view_base<
+        min_max_internal::index_view_content<Index, Type, Compare, false>,
+        Compare,
+        min_max_internal::reverse_predicate<Compare, Type> > base;
+    using base::calc;
+    using base::assign;
+    typedef std::pair<Index, Type> pair_type;
+    friend class min_max_internal::rhs_proxy<op_min_index_view>;
+
+public:
+    /** @name Constructors.
+     *
+     *  All op_min_index_view constructors simply pass their arguments on to the 
+     *  @ref view_base base class, except for the `(index, value [, compare])`
+     *  constructors, which create a `std::pair` containing the index and value.
+     */
+    //@{
+    
+    op_min_index_view() : base() {}
+    
+    template <typename T1>
+    op_min_index_view(const T1& x1) : base(x1) {}
+    
+    template <typename T1, typename T2>
+    op_min_index_view(const T1& x1, const T2& x2) : base(x1, x2) {}
+    
+    template <typename T1, typename T2, typename T3>
+    op_min_index_view(const T1& x1, const T2& x2, const T3& x3) : base(x1, x2, x3) {}
+    
+    op_min_index_view(const Index& i, const Type& v) : base(pair_type(i, v)) {}
+    
+    op_min_index_view(const Index& i, const Type& v, const typename base::compare_type* c) : 
+        base(pair_type(i, v), c) {}
+    
+    //@}    
+
+    /** Minimize with a value and index.
+     *
+     *  If @a x is greater than the current value of the view (as defined by 
+     *  the reducer’s comparator), or if the view was created without an 
+     *  initial value and its value has never been updated (with `calc_min()` 
+     *  or `= min_of()`), then the value of the view is set to @a x, and the
+     *  index is set to @a i..
+     *
+     *  @param  i   The index of the value @a x.
+     *  @param  x   The value to minimize the view’s value with.
+     *
+     *  @return     A reference to the view. (Allows 
+     *              `view.comp_min(i, a).comp_min(j, b)…`.)
+     */
+    op_min_index_view& calc_min(const Index& i, const Type& x) 
+        { calc(pair_type(i, x)); return *this; }
+
+    /** Maximize with an index/value pair.
+     *
+     *  If @a pair.second is less than the current value of the view (as
+     *  defined by the reducer’s comparator), or if the view was created 
+     *  without an initial value and its value has never been updated (with
+     *  `calc_min()` or `= min_of()`), then the value of the view is set to
+     *  @a pair.second, and the index is set to @a pair.first.
+     *
+     *  @param  pair    A pair containing a value to minimize the view’s value
+     *                  with and its associated index.
+     *
+     *  @return         A reference to the view. (Allows
+     *                  `view.comp_min(p1).comp_min(p2)…`.)
+     */
+    op_min_index_view& calc_min(const pair_type& pair) 
+        { calc(pair); return *this; }
+
+    /** Assign the result of a `min_of(view, index, value)` expression to the
+     *  view.
+     *
+     *  @param  rhs An rhs_proxy value created by a `min_of(view, index, value)`
+     *              expression.
+     *
+     *  @return     A reference to the view.
+     *
+     *  @see min_max_internal::view_base::rhs_proxy
+     */
+    op_min_index_view& operator=(const min_max_internal::rhs_proxy<op_min_index_view>& rhs) 
+        { assign(rhs); return *this; }
+};
+
+
+/** Compute the minimum of the value in a view and another value.
+ *
+ *  The result of this computation can only be assigned back to the original
+ *  view or used in another min_of() call. For example,
+ *
+ *      *reducer = min_of(*reducer, i, x);
+ *      *reducer = min_of(i, x, *reducer);
+ *
+ *  @see min_max_internal::min_min_view_base::rhs_proxy
+ */
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >
+min_of(const op_min_index_view<Index, Type, Compare>& view,
+       const Index& index, const Type& value)
+{
+    return min_max_internal::make_proxy(std::pair<Index, Type>(index, value), view);
+}
+
+/// @copydoc min_of(const op_min_index_view<Index, Type, Compare>&, const Index&, const Type&)
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >
+min_of(const Index& index, const Type& value,
+       const op_min_index_view<Index, Type, Compare>& view)
+{
+    return min_max_internal::make_proxy(std::pair<Index, Type>(index, value), view);
+}
+
+/// @copydoc min_of(const op_min_index_view<Index, Type, Compare>&, const Index&, const Type&)
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >
+min_of(const op_min_index_view<Index, Type, Compare>& view,
+       const std::pair<Index, Type>& pair)
+{
+    return min_max_internal::make_proxy(pair, view);
+}
+
+/// @copydoc min_of(const op_min_index_view<Index, Type, Compare>&, const Index&, const Type&)
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >
+min_of(const std::pair<Index, Type>& pair,
+       const op_min_index_view<Index, Type, Compare>& view)
+{
+    return min_max_internal::make_proxy(pair, view);
+}
+
+/** Nested computation of the minimum of the value in a view and other values.
+ *
+ *  Compute the minimum of the result of a min_of() call and another value.
+ *
+ *  The result of this computation can only be assigned back to the original
+ *  view or used in another min_of() call. For example,
+ *
+ *      *reducer = min_of(x, min_of(y, *reducer));
+ *      *reducer = min_of(min_of(*reducer, x), y);
+ *
+ *  @see min_max_internal::min_min_view_base::rhs_proxy
+ */
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >
+min_of(const min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >& proxy,
+       const Index& index, const Type& value)
+{
+    return proxy.calc(std::pair<Index, Type>(index, value));
+}
+
+/// @copydoc min_of(const min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >&, const Index&, const Type&)
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >
+min_of(const Index& index, const Type& value,
+       const min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >& proxy)
+{
+    return proxy.calc(std::pair<Index, Type>(index, value));
+}
+
+/// @copydoc min_of(const min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >&, const Index&, const Type&)
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >
+min_of(const min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >& proxy,
+       const std::pair<Index, Type>& pair)
+{
+    return proxy.calc(pair);
+}
+
+/// @copydoc min_of(const min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >&, const Index&, const Type&)
+template <typename Index, typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >
+min_of(const std::pair<Index, Type>& pair,
+       const min_max_internal::rhs_proxy< op_min_index_view<Index, Type, Compare> >& proxy)
+{
+    return proxy.calc(pair);
+}
+
+
+/** Monoid class for minimum reductions with index. Instantiate the
+ *  cilk::reducer template class with an op_min_index monoid to create a
+ *  min_index reducer class. For example, to compute the minimum of an array of 
+ *  `double` values and the array index of the min value:
+ *
+ *      cilk::reducer< cilk::op_min_index<unsigned, double> > r;
+ *
+ *  @see ReducersMinMax
+ *  @see op_min_index_view
+ */
+template < typename Index
+         , typename Type
+         , typename Compare=std::less<Type>
+         , bool     Align = false
+         >
+class op_min_index : public min_max_internal::monoid_base<op_min_index_view<Index, Type, Compare>, Align> 
+{
+    typedef min_max_internal::monoid_base<
+        op_min_index_view<Index, Type, Compare>, Align> base;
+public:
+    /// Construct with default comparator.
+    op_min_index() {}
+    /// Construct with specified comparator.
+    op_min_index(const Compare& compare) : base(compare) {}
+};
+
+//@}
+
+
+/** Deprecated maximum reducer wrapper class.
+ *
+ *  reducer_max is the same as @ref reducer<@ref op_max>, except that
+ *  reducer_max is a proxy for the contained view, so that accumulator
+ *  variable update operations can be applied directly to the reducer. For
+ *  example, a value is maximized with  a `reducer<%op_max>` with
+ *  `r->calc_max(a)`, but a value can be maximized with a `%reducer_max` with 
+ *  `r.calc_max(a)`.
+ *
+ *
+ *  @deprecated Users are strongly encouraged to use `reducer<monoid>`
+ *              reducers rather than the old wrappers like reducer_max. 
+ *              The `reducer<monoid>` reducers show the reducer/monoid/view
+ *              architecture more clearly, are more consistent in their
+ *              implementation, and present a simpler model for new
+ *              user-implemented reducers.
+ *
+ *  @note   Implicit conversions are provided between `%reducer_max` 
+ *          and `reducer<%op_max>`. This allows incremental code
+ *          conversion: old code that used `%reducer_max` can pass a
+ *          `%reducer_max` to a converted function that now expects a
+ *          pointer or reference to a `reducer<%op_max>`, and vice
+ *          versa. **But see  @ref redminmax_compatibility.**
+ *
+ *  @tparam Type    The value type of the reducer.
+ *  @tparam Compare The “less than” comparator type for the reducer.
+ *
+ *  @see op_max
+ *  @see op_max_view
+ *  @see reducer
+ *  @see ReducersMinMax
+ *  @ingroup ReducersMinMaxMaxValue
+ */
+template <typename Type, typename Compare=std::less<Type> >
+class reducer_max : public reducer< op_max<Type, Compare, true> >
+{
+    __CILKRTS_STATIC_ASSERT(
+        ::cilk::internal::class_is_empty< 
+            typename ::cilk::internal::binary_functor<Compare>::type >::value, 
+        "cilk::reducer_max<Type, Compare> only works with "
+        "an empty Compare class");
+    typedef reducer< op_max<Type, Compare, true> > base;
+public:
+    
+    /// Type of data in a reducer_max.
+    typedef Type                            basic_value_type;
+    
+    /// The view type for the reducer.
+    typedef typename base::view_type        view_type;
+    
+    /// The view type for the reducer.
+    typedef typename base::view_type        View;
+    
+    /// The monoid type for the reducer.
+    typedef typename base::monoid_type      monoid_type;
+    
+    /// The monoid type for the reducer.
+    typedef typename base::monoid_type      Monoid;
+
+    /// The view’s rhs proxy type.          
+    typedef min_max_internal::rhs_proxy<View> rhs_proxy;
+    
+    using base::view;
+
+    /** @name Constructors
+     */
+    //@{
+    
+    /// Construct the wrapper in its identity state (either `!is_set()`, or
+    /// `value() == identity value`).
+    reducer_max() : base() {}
+
+    /// Construct the wrapper with a specified initial value.
+    explicit reducer_max(const Type& initial_value) : base(initial_value) {}
+
+    /// Construct the wrapper in its identity state with a specified 
+    /// comparator.
+    explicit reducer_max(const Compare& comp) : base(comp) {}
+
+    /// Construct the wrapper with a specified initial value and a specified 
+    /// comparator.
+    reducer_max(const Type& initial_value, const Compare& comp)
+    :   base(initial_value, comp) {}
+    
+    //@}
+
+    /** @name Forwarded functions
+     *  @details Functions that update the contained accumulator variable are
+     *  simply forwarded to the contained @ref op_max_view. */
+    //@{
+
+    /// @copydoc cilk_lib_1_0::min_max_internal::view_content::is_set() const
+    bool is_set() const { return view().is_set(); }
+
+    /// @copydoc op_max_view::calc_max(const Type&)
+    reducer_max& calc_max(const Type& x) 
+        { view().calc_max(x); return *this; }
+
+    /// @copydoc op_max_view::operator=(const min_max_internal::rhs_proxy<op_max_view>&) 
+    reducer_max& operator=(const rhs_proxy& rhs)
+        { view() = rhs; return *this; }
+        
+    //@}
+
+    /** Allow read-only access to the value within the current view.
+     * 
+     *  @returns    A const reference to the value within the current view.
+     */
+    const Type& get_reference() const { return view().get_reference(); }
+    
+    /// @name Dereference
+    /** Dereferencing a wrapper is a no-op. It simply returns the wrapper.
+     *  Combined with the rule that a wrapper forwards view operations to the
+     *  view, this means that view operations can be written the same way on
+     *  reducers and wrappers, which is convenient for incrementally
+     *  converting code using wrappers to code using reducers. That is:
+     *
+     *      reducer< op_max<int> > r;
+     *      r->calc_max(a);      // *r returns the view
+     *                           // calc_max is a view member function
+     *
+     *      reducer_max<int> w;
+     *      w->calc_max(a);      // *w returns the wrapper
+     *                           // calc_max is a wrapper member function that
+     *                           // calls the corresponding view function
+     */
+    //@{
+    reducer_max&       operator*()       { return *this; }
+    reducer_max const& operator*() const { return *this; }
+
+    reducer_max*       operator->()       { return this; }
+    reducer_max const* operator->() const { return this; }
+    //@}
+    
+    /** @name Upcast
+     *  @details In Cilk library 0.9, reducers were always cache-aligned. In
+     *  library  1.0, reducer cache alignment is optional. By default, reducers
+     *  are unaligned (i.e., just naturally aligned), but legacy wrappers
+     *  inherit from cache-aligned reducers for binary compatibility.
+     *
+     *  This means that a wrapper will automatically be upcast to its aligned
+     *  reducer base class. The following conversion operators provide
+     *  pseudo-upcasts to the corresponding unaligned reducer class.
+     */
+    //@{
+    operator reducer< op_max<Type, Compare, false> >& ()
+    {
+        return *reinterpret_cast< reducer< op_max<Type, Compare, false> >* >(this);
+    }
+    
+    operator const reducer< op_max<Type, Compare, false> >& () const
+    {
+        return *reinterpret_cast< const reducer< op_max<Type, Compare, false> >* >(this);
+    }
+    //@}
+};
+
+
+/// @cond internal
+// The legacy definition of max_of(reducer_max, value) has different
+// behavior and a different return type than this definition. We add an 
+// unused third argument to this version of the function to give it a different
+// signature, so that they won’t end up sharing a single object file entry.
+struct max_of_1_0_t {};
+const max_of_1_0_t max_of_1_0 = {};
+/// @endcond
+
+/** Compute the maximum of the value in a reducer_max and another value.
+ *
+ *  @deprecated Because reducer_max is deprecated.
+ *
+ *  The result of this computation can only be assigned back to the original 
+ *  reducer or used in another max_of() call. For example,
+ *
+ *      reducer = max_of(reducer, x);
+ *      reducer = max_of(x, reducer);
+ *
+ *  @see min_max_internal::rhs_proxy
+ *
+ *  @ingroup ReducersMinMaxMaxValue
+ */
+template <typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_view<Type, Compare> >
+max_of(const reducer_max<Type, Compare>& r, const Type& value,
+        const max_of_1_0_t& = max_of_1_0)
+{
+    return min_max_internal::make_proxy(value, r.view());
+}
+
+/// @copydoc max_of(const reducer_max<Type, Compare>&, const Type&, const max_of_1_0_t&)
+/// @ingroup ReducersMinMaxMaxValue
+template <typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_max_view<Type, Compare> >
+max_of(const Type& value, const reducer_max<Type, Compare>& r,
+        const max_of_1_0_t& = max_of_1_0)
+{
+    return min_max_internal::make_proxy(value, r.view());
+}
+
+
+/** Deprecated minimum reducer wrapper class.
+ *
+ *  reducer_min is the same as @ref reducer<@ref op_min>, except that
+ *  reducer_min is a proxy for the contained view, so that accumulator
+ *  variable update operations can be applied directly to the reducer. For
+ *  example, a value is minimized with  a `reducer<%op_min>` with
+ *  `r->calc_min(a)`, but a value can be minimized with a `%reducer_min` with 
+ *  `r.calc_min(a)`.
+ *
+ *
+ *  @deprecated Users are strongly encouraged to use `reducer<monoid>`
+ *              reducers rather than the old wrappers like reducer_min. 
+ *              The `reducer<monoid>` reducers show the reducer/monoid/view
+ *              architecture more clearly, are more consistent in their
+ *              implementation, and present a simpler model for new
+ *              user-implemented reducers.
+ *
+ *  @note   Implicit conversions are provided between `%reducer_min` 
+ *          and `reducer<%op_min>`. This allows incremental code
+ *          conversion: old code that used `%reducer_min` can pass a
+ *          `%reducer_min` to a converted function that now expects a
+ *          pointer or reference to a `reducer<%op_min>`, and vice
+ *          versa. **But see  @ref redminmax_compatibility.**
+ *
+ *  @tparam Type    The value type of the reducer.
+ *  @tparam Compare The “less than” comparator type for the reducer.
+ *
+ *  @see op_min
+ *  @see op_min_view
+ *  @see reducer
+ *  @see ReducersMinMax
+ *  @ingroup ReducersMinMaxMinValue
+ */
+template <typename Type, typename Compare=std::less<Type> >
+class reducer_min : public reducer< op_min<Type, Compare, true> >
+{
+    __CILKRTS_STATIC_ASSERT(
+        ::cilk::internal::class_is_empty<
+            typename ::cilk::internal::binary_functor<Compare>::type >::value, 
+        "cilk::reducer_min<Type, Compare> only works with "
+        "an empty Compare class");
+    typedef reducer< op_min<Type, Compare, true> > base;
+public:
+    
+    /// Type of data in a reducer_min.
+    typedef Type                            basic_value_type;
+    
+    /// The view type for the reducer.
+    typedef typename base::view_type        view_type;
+    
+    /// The view type for the reducer.
+    typedef typename base::view_type        View;
+    
+    /// The monoid type for the reducer.
+    typedef typename base::monoid_type      monoid_type;
+    
+    /// The monoid type for the reducer.
+    typedef typename base::monoid_type      Monoid;
+
+    /// The view’s rhs proxy type.          
+    typedef min_max_internal::rhs_proxy<View> rhs_proxy;
+    
+    using base::view;
+
+    /** @name Constructors
+     */
+    //@{
+    
+    /// Construct the wrapper in its identity state (either `!is_set()`, or
+    /// `value() == identity value`).
+    reducer_min() : base() {}
+
+    /// Construct the wrapper with a specified initial value.
+    explicit reducer_min(const Type& initial_value) : base(initial_value) {}
+
+    /// Construct the wrapper in its identity state with a specified 
+    /// comparator.
+    explicit reducer_min(const Compare& comp) : base(comp) {}
+
+    /// Construct the wrapper with a specified initial value and a specified 
+    /// comparator.
+    reducer_min(const Type& initial_value, const Compare& comp)
+    :   base(initial_value, comp) {}
+    
+    //@}
+
+    /** @name Forwarded functions
+     *  @details Functions that update the contained accumulator variable are
+     *  simply forwarded to the contained @ref op_min_view. */
+    //@{
+
+    /// @copydoc cilk_lib_1_0::min_max_internal::view_content::is_set() const
+    bool is_set() const { return view().is_set(); }
+
+    /// @copydoc op_min_view::calc_min(const Type&)
+    reducer_min& calc_min(const Type& x) 
+        { view().calc_min(x); return *this; }
+
+    /// @copydoc op_min_view::operator=(const min_max_internal::rhs_proxy<op_min_view>&) 
+    reducer_min& operator=(const rhs_proxy& rhs)
+        { view() = rhs; return *this; }
+        
+    //@}
+
+    /** Allow read-only access to the value within the current view.
+     * 
+     *  @returns    A const reference to the value within the current view.
+     */
+    const Type& get_reference() const { return view().get_reference(); }
+    
+    /// @name Dereference
+    /** Dereferencing a wrapper is a no-op. It simply returns the wrapper.
+     *  Combined with the rule that a wrapper forwards view operations to the
+     *  view, this means that view operations can be written the same way on
+     *  reducers and wrappers, which is convenient for incrementally
+     *  converting code using wrappers to code using reducers. That is:
+     *
+     *      reducer< op_min<int> > r;
+     *      r->calc_min(a);      // *r returns the view
+     *                           // calc_min is a view member function
+     *
+     *      reducer_min<int> w;
+     *      w->calc_min(a);      // *w returns the wrapper
+     *                           // calc_min is a wrapper member function that
+     *                           // calls the corresponding view function
+     */
+    //@{
+    reducer_min&       operator*()       { return *this; }
+    reducer_min const& operator*() const { return *this; }
+
+    reducer_min*       operator->()       { return this; }
+    reducer_min const* operator->() const { return this; }
+    //@}
+    
+    /** @name Upcast
+     *  @details In Cilk library 0.9, reducers were always cache-aligned. In
+     *  library  1.0, reducer cache alignment is optional. By default, reducers
+     *  are unaligned (i.e., just naturally aligned), but legacy wrappers
+     *  inherit from cache-aligned reducers for binary compatibility.
+     *
+     *  This means that a wrapper will automatically be upcast to its aligned
+     *  reducer base class. The following conversion operators provide
+     *  pseudo-upcasts to the corresponding unaligned reducer class.
+     */
+    //@{
+    operator reducer< op_min<Type, Compare, false> >& ()
+    {
+        return *reinterpret_cast< reducer< op_min<Type, Compare, false> >* >(this);
+    }
+    
+    operator const reducer< op_min<Type, Compare, false> >& () const
+    {
+        return *reinterpret_cast< const reducer< op_min<Type, Compare, false> >* >(this);
+    }
+    //@}
+};
+
+
+/** Compute the minimum of a reducer and a value.
+ *
+ *  @deprecated Because reducer_min is deprecated.
+ */
+//@{
+// The legacy definition of min_of(reducer_min, value) has different
+// behavior and a different return type than this definition. We add an 
+// unused third argument to this version of the function to give it a different
+// signature, so that they won’t end up sharing a single object file entry.
+struct min_of_1_0_t {};
+const min_of_1_0_t min_of_1_0 = {};
+
+template <typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_view<Type, Compare> >
+min_of(const reducer_min<Type, Compare>& r, const Type& value,
+        const min_of_1_0_t& = min_of_1_0)
+{
+    return min_max_internal::make_proxy(value, r.view());
+}
+
+template <typename Type, typename Compare>
+inline min_max_internal::rhs_proxy< op_min_view<Type, Compare> >
+min_of(const Type& value, const reducer_min<Type, Compare>& r,
+        const min_of_1_0_t& = min_of_1_0)
+{
+    return min_max_internal::make_proxy(value, r.view());
+}
+//@}
+
+
+/** Deprecated maximum with index reducer wrapper class.
+ *
+ *  reducer_max_index is the same as @ref reducer<@ref op_max_index>, except
+ *  that reducer_max_index is a proxy for the contained view, so that
+ *  accumulator variable update operations can be applied directly to the
+ *  reducer. For example, a value is maximized with  a `reducer<%op_max_index>`
+ *  with `r->calc_max(i, a)`, but a value can be maximized with a 
+ *  `%reducer_max` with `r.calc_max(i, aa)`.
+ *
+ *
+ *  @deprecated Users are strongly encouraged to use `reducer<monoid>`
+ *              reducers rather than the old wrappers like reducer_max. 
+ *              The `reducer<monoid>` reducers show the reducer/monoid/view
+ *              architecture more clearly, are more consistent in their
+ *              implementation, and present a simpler model for new
+ *              user-implemented reducers.
+ *
+ *  @note   Implicit conversions are provided between `%reducer_max_index` 
+ *          and `reducer<%op_max_index>`. This allows incremental code
+ *          conversion: old code that used `%reducer_max_index` can pass a
+ *          `%reducer_max_index` to a converted function that now expects a
+ *          pointer or reference to a `reducer<%op_max_index>`, and vice
+ *          versa. **But see  @ref redminmax_compatibility.**
+ *
+ *  @tparam Index   The index type of the reducer.
+ *  @tparam Type    The value type of the reducer.
+ *  @tparam Compare The “less than” comparator type for the reducer.
+ *
+ *  @see op_max_index
+ *  @see op_max_index_view
+ *  @see reducer
+ *  @see ReducersMinMax
+ *  @ingroup ReducersMinMaxMaxIndex
+ */
+template < typename Index
+         , typename Type
+         , typename Compare = std::less<Type>
+         >
+class reducer_max_index : 
+    public reducer< op_max_index<Index, Type, Compare, true> >
+{
+    __CILKRTS_STATIC_ASSERT(
+        ::cilk::internal::class_is_empty< 
+            typename ::cilk::internal::binary_functor<Compare>::type >::value, 
+        "cilk::reducer_max_index<Type, Compare> only works with "
+        "an empty Compare class");
+    typedef reducer< op_max_index<Index, Type, Compare, true> > base;
+public:
+    
+    /// Type of data in a reducer_max_index.
+    typedef Type                            basic_value_type;
+    
+    /// The view type for the reducer.
+    typedef typename base::view_type        view_type;
+    
+    /// The view type for the reducer.
+    typedef typename base::view_type        View;
+    
+    /// The monoid type for the reducer.
+    typedef typename base::monoid_type      monoid_type;
+    
+    /// The monoid type for the reducer.
+    typedef typename base::monoid_type      Monoid;
+
+    /// The view’s rhs proxy type.          
+    typedef min_max_internal::rhs_proxy<View> rhs_proxy;
+    
+    using base::view;
+
+    /** @name Constructors
+     */
+    //@{
+    
+    /// Construct the wrapper in its identity state (`!is_set()`).
+    reducer_max_index() : base() {}
+
+    /// Construct with a specified initial index and value.
+    reducer_max_index(const Index& initial_index,
+                      const Type& initial_value)
+    : base(initial_index, initial_value) {}
+
+    /// Construct the wrapper with a specified comparator.
+    explicit reducer_max_index(const Compare& comp) : base(comp) {}
+
+    /// Construct the wrapper with a specified initial index, value, 
+    /// and comparator.
+    reducer_max_index(const Index& initial_index,
+                      const Type& initial_value,
+                      const Compare& comp)
+    : base(initial_index, initial_value, comp) {}
+
+    //@}
+    
+    /** @name Set / Get
+     */
+    //@{
+    
+    /// Set the index and value of this object.
+    void set_value(const Index& index, const Type& value)
+        { base::set_value(std::make_pair(index, value)); }
+
+    /// Return the maximum value.
+    const Type& get_value() const 
+        { return view().get_reference(); }
+
+    /// Return the maximum index.
+    const Index& get_index() const 
+        { return view().get_index_reference(); }
+
+    /// Return a const reference to value data member in the view.
+    const Type& get_reference() const
+        { return view().get_reference(); }
+    
+    /// Return a const reference to index data member in the view.
+    const Index& get_index_reference() const 
+        { return view().get_index_reference(); }
+    
+    //@}
+    
+    /** @name Forwarded functions
+     *  @details Functions that update the contained accumulator variable are
+     *  simply forwarded to the contained @ref op_max_view. */
+    //@{
+
+    /// @copydoc cilk_lib_1_0::min_max_internal::view_content::is_set() const
+    bool is_set() const { return view().is_set(); }
+
+    /// @copydoc op_max_index_view::calc_max(const Index&, const Type&)
+    reducer_max_index& calc_max(const Index& i, const Type& x) 
+        { view().calc_max(i, x); return *this; }
+
+    /// @copydoc op_max_view::operator=(const min_max_internal::rhs_proxy<op_max_view>&) 
+    reducer_max_index& operator=(const rhs_proxy& rhs)
+        { view() = rhs; return *this; }
+        
+    //@}
+
+    /// @name Dereference
+    /** Dereferencing a wrapper is a no-op. It simply returns the wrapper.
+     *  Combined with the rule that a wrapper forwards view operations to the
+     *  view, this means that view operations can be written the same way on
+     *  reducers and wrappers, which is convenient for incrementally
+     *  converting code using wrappers to code using reducers. That is:
+     *
+     *      reducer< op_max_index<int, int> > r;
+     *      r->calc_max(i, a);   // *r returns the view
+     *                           // calc_max is a view member function
+     *
+     *      reducer_max_index<int, int> w;
+     *      w->calc_max(i, a);   // *w returns the wrapper
+     *                           // calc_max is a wrapper member function that
+     *                           // calls the corresponding view function
+     */
+    //@{
+    reducer_max_index&       operator*()       { return *this; }
+    reducer_max_index const& operator*() const { return *this; }
+
+    reducer_max_index*       operator->()       { return this; }
+    reducer_max_index const* operator->() const { return this; }
+    //@}
+    
+    /** @name Upcast
+     *  @details In Cilk library 0.9, reducers were always cache-aligned. In
+     *  library  1.0, reducer cache alignment is optional. By default, reducers
+     *  are unaligned (i.e., just naturally aligned), but legacy wrappers
+     *  inherit from cache-aligned reducers for binary compatibility.
+     *
+     *  This means that a wrapper will automatically be upcast to its aligned
+     *  reducer base class. The following conversion operators provide
+     *  pseudo-upcasts to the corresponding unaligned reducer class.
+     */
+    //@{
+    operator reducer< op_max_index<Index, Type, Compare, false> >& ()
+    {
+        return *reinterpret_cast< reducer< op_max_index<Index, Type, Compare, false> >* >(this);
+    }
+    
+    operator const reducer< op_max_index<Index, Type, Compare, false> >& () const
+    {
+        return *reinterpret_cast< const reducer< op_max_index<Index, Type, Compare, false> >* >(this);
+    }
+    //@}
+    
+};
+
+
+/** Deprecated minimum with index reducer wrapper class.
+ *
+ *  reducer_min_index is the same as @ref reducer<@ref op_min_index>, except
+ *  that reducer_min_index is a proxy for the contained view, so that
+ *  accumulator variable update operations can be applied directly to the
+ *  reducer. For example, a value is minimized with  a `reducer<%op_min_index>`
+ *  with `r->calc_min(i, a)`, but a value can be minimized with a 
+ *  `%reducer_min` with `r.calc_min(i, aa)`.
+ *
+ *
+ *  @deprecated Users are strongly encouraged to use `reducer<monoid>`
+ *              reducers rather than the old wrappers like reducer_min. 
+ *              The `reducer<monoid>` reducers show the reducer/monoid/view
+ *              architecture more clearly, are more consistent in their
+ *              implementation, and present a simpler model for new
+ *              user-implemented reducers.
+ *
+ *  @note   Implicit conversions are provided between `%reducer_min_index` 
+ *          and `reducer<%op_min_index>`. This allows incremental code
+ *          conversion: old code that used `%reducer_min_index` can pass a
+ *          `%reducer_min_index` to a converted function that now expects a
+ *          pointer or reference to a `reducer<%op_min_index>`, and vice
+ *          versa. **But see  @ref redminmax_compatibility.**
+ *
+ *  @tparam Index   The index type of the reducer.
+ *  @tparam Type    The value type of the reducer.
+ *  @tparam Compare The “less than” comparator type for the reducer.
+ *
+ *  @see op_min_index
+ *  @see op_min_index_view
+ *  @see reducer
+ *  @see ReducersMinMax
+ *  @ingroup ReducersMinMaxMinIndex
+ */
+template < typename Index
+         , typename Type
+         , typename Compare = std::less<Type>
+         >
+class reducer_min_index : 
+    public reducer< op_min_index<Index, Type, Compare, true> >
+{
+    __CILKRTS_STATIC_ASSERT(
+        ::cilk::internal::class_is_empty< 
+            typename ::cilk::internal::binary_functor<Compare>::type >::value, 
+        "cilk::reducer_min_index<Type, Compare> only works with "
+        "an empty Compare class");
+    typedef reducer< op_min_index<Index, Type, Compare, true> > base;
+public:
+    
+    /// Type of data in a reducer_min_index.
+    typedef Type                            basic_value_type;
+    
+    /// The view type for the reducer.
+    typedef typename base::view_type        view_type;
+    
+    /// The view type for the reducer.
+    typedef typename base::view_type        View;
+    
+    /// The monoid type for the reducer.
+    typedef typename base::monoid_type      monoid_type;
+    
+    /// The monoid type for the reducer.
+    typedef typename base::monoid_type      Monoid;
+
+    /// The view’s rhs proxy type.          
+    typedef min_max_internal::rhs_proxy<View> rhs_proxy;
+    
+    using base::view;
+
+    /** @name Constructors
+     */
+    //@{
+    
+    /// Construct the wrapper in its identity state (`!is_set()`).
+    reducer_min_index() : base() {}
+
+    /// Construct with a specified initial index and value.
+    reducer_min_index(const Index& initial_index,
+                      const Type& initial_value)
+    : base(initial_index, initial_value) {}
+
+    /// Construct the wrapper with a specified comparator.
+    explicit reducer_min_index(const Compare& comp) : base(comp) {}
+
+    /// Construct the wrapper with a specified initial index, value, 
+    /// and comparator.
+    reducer_min_index(const Index& initial_index,
+                      const Type& initial_value,
+                      const Compare& comp)
+    : base(initial_index, initial_value, comp) {}
+
+    //@}
+    
+    /** @name Set / Get
+     */
+    //@{
+    
+    /// Set the index and value of this object.
+    void set_value(const Index& index, const Type& value)
+        { base::set_value(std::make_pair(index, value)); }
+
+    /// Return the minimum value.
+    const Type& get_value() const 
+        { return view().get_reference(); }
+
+    /// Return the minimum index.
+    const Index& get_index() const 
+        { return view().get_index_reference(); }
+
+    /// Return a const reference to value data member in the view.
+    const Type& get_reference() const
+        { return view().get_reference(); }
+    
+    /// Return a const reference to index data member in the view.
+    const Index& get_index_reference() const 
+        { return view().get_index_reference(); }
+    
+    //@}
+    
+    /** @name Forwarded functions
+     *  @details Functions that update the contained accumulator variable are
+     *  simply forwarded to the contained @ref op_min_view. */
+    //@{
+
+    /// @copydoc cilk_lib_1_0::min_max_internal::view_content::is_set() const
+    bool is_set() const { return view().is_set(); }
+
+    /// @copydoc op_min_index_view::calc_min(const Index&, const Type&)
+    reducer_min_index& calc_min(const Index& i, const Type& x) 
+        { view().calc_min(i, x); return *this; }
+
+    /// @copydoc op_min_view::operator=(const min_max_internal::rhs_proxy<op_min_view>&) 
+    reducer_min_index& operator=(const rhs_proxy& rhs)
+        { view() = rhs; return *this; }
+        
+    //@}
+
+    /// @name Dereference
+    /** Dereferencing a wrapper is a no-op. It simply returns the wrapper.
+     *  Combined with the rule that a wrapper forwards view operations to the
+     *  view, this means that view operations can be written the same way on
+     *  reducers and wrappers, which is convenient for incrementally
+     *  converting code using wrappers to code using reducers. That is:
+     *
+     *      reducer< op_min_index<int, int> > r;
+     *      r->calc_min(i, a);   // *r returns the view
+     *                           // calc_min is a view member function
+     *
+     *      reducer_min_index<int, int> w;
+     *      w->calc_min(i, a);   // *w returns the wrapper
+     *                           // calc_min is a wrapper member function that
+     *                           // calls the corresponding view function
+     */
+    //@{
+    reducer_min_index&       operator*()       { return *this; }
+    reducer_min_index const& operator*() const { return *this; }
+
+    reducer_min_index*       operator->()       { return this; }
+    reducer_min_index const* operator->() const { return this; }
+    //@}
+    
+    /** @name Upcast
+     *  @details In Cilk library 0.9, reducers were always cache-aligned. In
+     *  library  1.0, reducer cache alignment is optional. By default, reducers
+     *  are unaligned (i.e., just naturally aligned), but legacy wrappers
+     *  inherit from cache-aligned reducers for binary compatibility.
+     *
+     *  This means that a wrapper will automatically be upcast to its aligned
+     *  reducer base class. The following conversion operators provide
+     *  pseudo-upcasts to the corresponding unaligned reducer class.
+     */
+    //@{
+    operator reducer< op_min_index<Index, Type, Compare, false> >& ()
+    {
+        return *reinterpret_cast< reducer< op_min_index<Index, Type, Compare, false> >* >(this);
+    }
+    
+    operator const reducer< op_min_index<Index, Type, Compare, false> >& () const
+    {
+        return *reinterpret_cast< const reducer< op_min_index<Index, Type, Compare, false> >* >(this);
+    }
+    //@}
+    
+};
+
+
+#ifndef CILK_LIBRARY_0_9_REDUCER_MINMAX
+} // namespace cilk_lib_1_0
+using namespace cilk_lib_1_0;
+#endif
+
+
+/// @cond internal
+/** Metafunction specialization for reducer conversion.
+ *
+ *  These specializations of the @ref legacy_reducer_downcast template class
+ *  defined in reducer.h causes each `reducer< op_xxxx<Type> >` classes to have
+ *  an `operator reducer_xxxx<Type>& ()` conversion operator that statically
+ *  downcasts the `reducer<op_xxxx>` to the corresponding `reducer_xxxx` type.
+ *  (The reverse conversion, from `reducer_xxxx` to `reducer<op_xxxx>`, is just
+ *  an upcast, which is provided for free by the language.)
+ */
+template <typename Type, typename Compare, bool Align>
+struct legacy_reducer_downcast< reducer< op_max<Type, Compare, Align> > >
+{
+    typedef reducer_max<Type> type;
+};
+
+template <typename Type, typename Compare, bool Align>
+struct legacy_reducer_downcast< reducer< op_min<Type, Compare, Align> > >
+{
+    typedef reducer_min<Type> type;
+};
+
+template <typename Index, typename Type, typename Compare, bool Align>
+struct legacy_reducer_downcast< reducer< op_max_index<Index, Type, Compare, Align> > >
+{
+    typedef reducer_max_index<Index, Type> type;
+};
+
+template <typename Index, typename Type, typename Compare, bool Align>
+struct legacy_reducer_downcast< reducer< op_min_index<Index, Type, Compare, Align> > >
+{
+    typedef reducer_min_index<Index, Type> type;
+};
+/// @endcond
+
+} // namespace cilk
+
+#endif // __cplusplus
+
+
+/** @name C language reducer macros
+ *
+ *  These macros are used to declare and work with numeric minimum and maximum reducers in C
+ *  code.
+ *
+ *  @see @ref page_reducers_in_c
+ */
+ //@{
+
+#ifdef CILK_C_DEFINE_REDUCERS
+
+/* Integer min/max constants */
+#include <limits.h>
+
+/* Wchar_t min/max constants */
+#if defined(_MSC_VER) || defined(ANDROID)
+#   include <wchar.h>
+#else
+#   include <stdint.h>
+#endif
+
+/* Floating-point min/max constants */
+#include <math.h>
+#ifndef HUGE_VALF
+    static const unsigned int __huge_valf[] = {0x7f800000};
+#   define HUGE_VALF (*((const float *)__huge_valf))
+#endif
+
+#ifndef HUGE_VALL
+    static const unsigned int __huge_vall[] = {0, 0, 0x00007f80, 0};
+#   define HUGE_VALL (*((const long double *)__huge_vall))
+#endif
+
+#endif
+
+/** Max reducer type name.
+ *
+ *  This macro expands into the identifier which is the name of the max reducer
+ *  type for a specified numeric type.
+ *
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying the type of the
+ *              reducer.
+ *
+ *  @see @ref reducers_c_predefined
+ */
+#define CILK_C_REDUCER_MAX_TYPE(tn)                                         \
+    __CILKRTS_MKIDENT(cilk_c_reducer_max_,tn)
+
+/** Declare a max reducer object.
+ *
+ *  This macro expands into a declaration of a max reducer object for a specified numeric
+ *  type. For example:
+ *
+ *      CILK_C_REDUCER_MAX(my_reducer, double, -DBL_MAX);
+ *
+ *  @param  obj The variable name to be used for the declared reducer object.
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying the type of the
+ *              reducer.
+ *  @param  v   The initial value for the reducer. (A value which can be assigned to the 
+ *              numeric type represented by @a tn.)
+ *
+ *  @see @ref reducers_c_predefined
+ */
+#define CILK_C_REDUCER_MAX(obj,tn,v)                                        \
+    CILK_C_REDUCER_MAX_TYPE(tn) obj =                                       \
+        CILK_C_INIT_REDUCER(_Typeof(obj.value),                             \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_max_reduce_,tn),   \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_max_identity_,tn), \
+                        __cilkrts_hyperobject_noop_destroy, v)
+
+/** Maximize with a value.
+ *
+ *  `CILK_C_REDUCER_MAX_CALC(reducer, v)` sets the current view of the
+ *  reducer to the max of its previous value and a specified new value.
+ *  This is equivalent to
+ *
+ *      REDUCER_VIEW(reducer) = max(REDUCER_VIEW(reducer), v)
+ *
+ *  @param reducer  The reducer whose contained value is to be updated.
+ *  @param v        The value that it is to be maximized with.
+ */
+#define CILK_C_REDUCER_MAX_CALC(reducer, v) do {                            \
+    _Typeof((reducer).value)* view = &(REDUCER_VIEW(reducer));              \
+    _Typeof(v) __value = (v);                                               \
+    if (*view < __value) {                                                  \
+        *view = __value;                                                    \
+    } } while (0)
+
+/// @cond internal
+
+/** Declare the max reducer functions for a numeric type.
+ *
+ *  This macro expands into external function declarations for functions which implement
+ *  the reducer functionality for the max reducer type for a specified numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer type name,
+ *              function names, etc.
+ */
+#define CILK_C_REDUCER_MAX_DECLARATION(t,tn,id)                             \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_MAX_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_max,tn,l,r);         \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_max,tn);
+/** Define the max reducer functions for a numeric type.
+ *
+ *  This macro expands into function definitions for functions which implement the
+ *  reducer functionality for the max reducer type for a specified numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer type name,
+ *              function names, etc.
+ */
+#define CILK_C_REDUCER_MAX_DEFINITION(t,tn,id)                           \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_MAX_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_max,tn,l,r)          \
+        { if (*(t*)l < *(t*)r) *(t*)l = *(t*)r; }                        \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_max,tn)            \
+        { *(t*)v = id; }
+//@{
+/** @def CILK_C_REDUCER_MAX_INSTANCE 
+ *  @brief Declare or define implementation functions for a reducer type.
+ *
+ *  In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS` will be defined, and
+ *  this macro will generate reducer implementation functions. Everywhere else, `CILK_C_DEFINE_REDUCERS`
+ *  will be undefined, and this macro will expand into external declarations for the functions.
+ */
+#ifdef CILK_C_DEFINE_REDUCERS
+#   define CILK_C_REDUCER_MAX_INSTANCE(t,tn,id)  \
+        CILK_C_REDUCER_MAX_DEFINITION(t,tn,id)
+#else
+#   define CILK_C_REDUCER_MAX_INSTANCE(t,tn,id)  \
+        CILK_C_REDUCER_MAX_DECLARATION(t,tn,id)
+#endif
+//@}
+
+/*  Declare or define an instance of the reducer type and its functions for each 
+ *  numeric type.
+ */
+__CILKRTS_BEGIN_EXTERN_C
+CILK_C_REDUCER_MAX_INSTANCE(char,               char,       CHAR_MIN)
+CILK_C_REDUCER_MAX_INSTANCE(unsigned char,      uchar,      0)
+CILK_C_REDUCER_MAX_INSTANCE(signed char,        schar,      SCHAR_MIN)
+CILK_C_REDUCER_MAX_INSTANCE(wchar_t,            wchar_t,    WCHAR_MIN)
+CILK_C_REDUCER_MAX_INSTANCE(short,              short,      SHRT_MIN)
+CILK_C_REDUCER_MAX_INSTANCE(unsigned short,     ushort,     0)
+CILK_C_REDUCER_MAX_INSTANCE(int,                int,        INT_MIN)
+CILK_C_REDUCER_MAX_INSTANCE(unsigned int,       uint,       0)
+CILK_C_REDUCER_MAX_INSTANCE(unsigned int,       unsigned,   0) // alternate name
+CILK_C_REDUCER_MAX_INSTANCE(long,               long,       LONG_MIN)
+CILK_C_REDUCER_MAX_INSTANCE(unsigned long,      ulong,      0)
+CILK_C_REDUCER_MAX_INSTANCE(long long,          longlong,   LLONG_MIN)
+CILK_C_REDUCER_MAX_INSTANCE(unsigned long long, ulonglong,  0)
+CILK_C_REDUCER_MAX_INSTANCE(float,              float,      -HUGE_VALF)
+CILK_C_REDUCER_MAX_INSTANCE(double,             double,     -HUGE_VAL)
+CILK_C_REDUCER_MAX_INSTANCE(long double,        longdouble, -HUGE_VALL)
+__CILKRTS_END_EXTERN_C
+
+/// @endcond
+
+/** Max_index reducer type name.
+ *
+ *  This macro expands into the identifier which is the name of the max_index reducer
+ *  type for a specified numeric type.
+ *
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying the type of the
+ *              reducer.
+ *
+ *  @see @ref reducers_c_predefined
+ */
+#define CILK_C_REDUCER_MAX_INDEX_TYPE(tn)                                         \
+    __CILKRTS_MKIDENT(cilk_c_reducer_max_index_,tn)
+
+/** Declare an op_max_index reducer object.
+ *
+ *  This macro expands into a declaration of a max_index reducer object for a specified
+ *  numeric type. For example:
+ *
+ *      CILK_C_REDUCER_MAX_INDEX(my_reducer, double, -DBL_MAX_INDEX);
+ *
+ *  @param  obj The variable name to be used for the declared reducer object.
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying the type of the
+ *              reducer.
+ *  @param  v   The initial value for the reducer. (A value which can be assigned to the 
+ *              numeric type represented by @a tn.)
+ *
+ *  @see @ref reducers_c_predefined
+ */
+#define CILK_C_REDUCER_MAX_INDEX(obj,tn,v)                                        \
+    CILK_C_REDUCER_MAX_INDEX_TYPE(tn) obj =                                       \
+        CILK_C_INIT_REDUCER(_Typeof(obj.value),                             \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_max_index_reduce_,tn),   \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_max_index_identity_,tn), \
+                        __cilkrts_hyperobject_noop_destroy, {0, v})
+
+/** Maximize with a value.
+ *
+ *  `CILK_C_REDUCER_MAX_INDEX_CALC(reducer, i, v)` sets the current view of the
+ *  reducer to the max of its previous value and a specified new value.
+ *  This is equivalent to
+ *
+ *      REDUCER_VIEW(reducer) = max_index(REDUCER_VIEW(reducer), v)
+ *
+ *  If the value of the reducer is changed to @a v, then the index of the reducer is
+ *  changed to @a i. 
+ *
+ *  @param reducer  The reducer whose contained value and index are to be updated.
+ *  @param i        The index associated with the new value.
+ *  @param v        The value that it is to be maximized with.
+ */
+#define CILK_C_REDUCER_MAX_INDEX_CALC(reducer, i, v) do {                   \
+    _Typeof((reducer).value)* view = &(REDUCER_VIEW(reducer));              \
+    _Typeof(v) __value = (v);                                               \
+    if (view->value < __value) {                                            \
+        view->index = (i);                                                  \
+        view->value = __value;                                              \
+    } } while (0)
+
+/// @cond internal
+
+/** Declare the max_index view type.
+ *
+ *  The view of a max_index reducer is a structure containing both the
+ *  maximum value for the reducer and the index that was associated with
+ *  that value in the sequence of input values.
+ */
+#define CILK_C_REDUCER_MAX_INDEX_VIEW(t,tn)                                  \
+    typedef struct {                                                         \
+        __STDNS ptrdiff_t index;                                             \
+        t                 value;                                             \
+    } __CILKRTS_MKIDENT(cilk_c_reducer_max_index_view_,tn)
+
+/** Declare the max_index reducer functions for a numeric type.
+ *
+ *  This macro expands into external function declarations for functions which implement
+ *  the reducer functionality for the max_index reducer type for a specified numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer type name,
+ *              function names, etc.
+ */
+#define CILK_C_REDUCER_MAX_INDEX_DECLARATION(t,tn,id)                       \
+    CILK_C_REDUCER_MAX_INDEX_VIEW(t,tn);                                    \
+    typedef CILK_C_DECLARE_REDUCER(                                         \
+        __CILKRTS_MKIDENT(cilk_c_reducer_max_index_view_,tn))               \
+            CILK_C_REDUCER_MAX_INDEX_TYPE(tn);                              \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_max_index,tn,l,r);      \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_max_index,tn);
+/** Define the max_index reducer functions for a numeric type.
+ *
+ *  This macro expands into function definitions for functions which implement the
+ *  reducer functionality for the max_index reducer type for a specified numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer type name,
+ *              function names, etc.
+ */
+#define CILK_C_REDUCER_MAX_INDEX_DEFINITION(t,tn,id)                           \
+    CILK_C_REDUCER_MAX_INDEX_VIEW(t,tn);                                    \
+    typedef CILK_C_DECLARE_REDUCER(                                         \
+        __CILKRTS_MKIDENT(cilk_c_reducer_max_index_view_,tn))               \
+            CILK_C_REDUCER_MAX_INDEX_TYPE(tn);                              \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_max_index,tn,l,r)          \
+        { typedef __CILKRTS_MKIDENT(cilk_c_reducer_max_index_view_,tn) view_t; \
+          if (((view_t*)l)->value < ((view_t*)r)->value)                       \
+              *(view_t*)l = *(view_t*)r; }                                     \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_max_index,tn)            \
+        { typedef __CILKRTS_MKIDENT(cilk_c_reducer_max_index_view_,tn) view_t; \
+          ((view_t*)v)->index = 0; ((view_t*)v)->value = id; }
+//@{
+/** @def CILK_C_REDUCER_MAX_INDEX_INSTANCE 
+ *  @brief Declare or define implementation functions for a reducer type.
+ *
+ *  In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS` will be defined, and
+ *  this macro will generate reducer implementation functions. Everywhere else, `CILK_C_DEFINE_REDUCERS`
+ *  will be undefined, and this macro will expand into external declarations for the functions.
+ */
+#ifdef CILK_C_DEFINE_REDUCERS
+#   define CILK_C_REDUCER_MAX_INDEX_INSTANCE(t,tn,id)  \
+        CILK_C_REDUCER_MAX_INDEX_DEFINITION(t,tn,id)
+#else
+#   define CILK_C_REDUCER_MAX_INDEX_INSTANCE(t,tn,id)  \
+        CILK_C_REDUCER_MAX_INDEX_DECLARATION(t,tn,id)
+#endif
+//@}
+
+/*  Declare or define an instance of the reducer type and its functions for each 
+ *  numeric type.
+ */
+__CILKRTS_BEGIN_EXTERN_C
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(char,               char,       CHAR_MIN)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(unsigned char,      uchar,      0)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(signed char,        schar,      SCHAR_MIN)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(wchar_t,            wchar_t,    WCHAR_MIN)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(short,              short,      SHRT_MIN)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(unsigned short,     ushort,     0)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(int,                int,        INT_MIN)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(unsigned int,       uint,       0)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(unsigned int,       unsigned,   0) // alternate name
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(long,               long,       LONG_MIN)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(unsigned long,      ulong,      0)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(long long,          longlong,   LLONG_MIN)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(unsigned long long, ulonglong,  0)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(float,              float,      -HUGE_VALF)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(double,             double,     -HUGE_VAL)
+CILK_C_REDUCER_MAX_INDEX_INSTANCE(long double,        longdouble, -HUGE_VALL)
+__CILKRTS_END_EXTERN_C
+
+/// @endcond
+
+/** Min reducer type name.
+ *
+ *  This macro expands into the identifier which is the name of the min reducer
+ *  type for a specified numeric type.
+ *
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying the type of the
+ *              reducer.
+ *
+ *  @see @ref reducers_c_predefined
+ */
+#define CILK_C_REDUCER_MIN_TYPE(tn)                                         \
+    __CILKRTS_MKIDENT(cilk_c_reducer_min_,tn)
+
+/** Declare a min reducer object.
+ *
+ *  This macro expands into a declaration of a min reducer object for a specified numeric
+ *  type. For example:
+ *
+ *      CILK_C_REDUCER_MIN(my_reducer, double, DBL_MAX);
+ *
+ *  @param  obj The variable name to be used for the declared reducer object.
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying the type of the
+ *              reducer.
+ *  @param  v   The initial value for the reducer. (A value which can be assigned to the 
+ *              numeric type represented by @a tn.)
+ *
+ *  @see @ref reducers_c_predefined
+ */
+#define CILK_C_REDUCER_MIN(obj,tn,v)                                        \
+    CILK_C_REDUCER_MIN_TYPE(tn) obj =                                       \
+        CILK_C_INIT_REDUCER(_Typeof(obj.value),                             \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_min_reduce_,tn),   \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_min_identity_,tn), \
+                        __cilkrts_hyperobject_noop_destroy, v)
+
+/** Minimize with a value.
+ *
+ *  `CILK_C_REDUCER_MIN_CALC(reducer, v)` sets the current view of the
+ *  reducer to the min of its previous value and a specified new value.
+ *  This is equivalent to
+ *
+ *      REDUCER_VIEW(reducer) = min(REDUCER_VIEW(reducer), v)
+ *
+ *  @param reducer  The reducer whose contained value is to be updated.
+ *  @param v        The value that it is to be minimized with.
+ */
+#define CILK_C_REDUCER_MIN_CALC(reducer, v) do {                            \
+    _Typeof((reducer).value)* view = &(REDUCER_VIEW(reducer));              \
+    _Typeof(v) __value = (v);                                               \
+    if (*view > __value) {                                                  \
+        *view = __value;                                                    \
+    } } while (0)
+
+/// @cond internal
+
+/** Declare the min reducer functions for a numeric type.
+ *
+ *  This macro expands into external function declarations for functions which implement
+ *  the reducer functionality for the min reducer type for a specified numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer type name,
+ *              function names, etc.
+ */
+#define CILK_C_REDUCER_MIN_DECLARATION(t,tn,id)                             \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_MIN_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_min,tn,l,r);         \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_min,tn);
+/** Define the min reducer functions for a numeric type.
+ *
+ *  This macro expands into function definitions for functions which implement the
+ *  reducer functionality for the min reducer type for a specified numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer type name,
+ *              function names, etc.
+ */
+#define CILK_C_REDUCER_MIN_DEFINITION(t,tn,id)                           \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_MIN_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_min,tn,l,r)          \
+        { if (*(t*)l > *(t*)r) *(t*)l = *(t*)r; }                        \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_min,tn)            \
+        { *(t*)v = id; }
+//@{
+/** @def CILK_C_REDUCER_MIN_INSTANCE 
+ *  @brief Declare or define implementation functions for a reducer type.
+ *
+ *  In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS` will be defined, and
+ *  this macro will generate reducer implementation functions. Everywhere else, `CILK_C_DEFINE_REDUCERS`
+ *  will be undefined, and this macro will expand into external declarations for the functions.
+ */
+#ifdef CILK_C_DEFINE_REDUCERS
+#   define CILK_C_REDUCER_MIN_INSTANCE(t,tn,id)  \
+        CILK_C_REDUCER_MIN_DEFINITION(t,tn,id)
+#else
+#   define CILK_C_REDUCER_MIN_INSTANCE(t,tn,id)  \
+        CILK_C_REDUCER_MIN_DECLARATION(t,tn,id)
+#endif
+//@}
+
+/*  Declare or define an instance of the reducer type and its functions for each 
+ *  numeric type.
+ */
+__CILKRTS_BEGIN_EXTERN_C
+CILK_C_REDUCER_MIN_INSTANCE(char,               char,       CHAR_MAX)
+CILK_C_REDUCER_MIN_INSTANCE(unsigned char,      uchar,      CHAR_MAX)
+CILK_C_REDUCER_MIN_INSTANCE(signed char,        schar,      SCHAR_MAX)
+CILK_C_REDUCER_MIN_INSTANCE(wchar_t,            wchar_t,    WCHAR_MAX)
+CILK_C_REDUCER_MIN_INSTANCE(short,              short,      SHRT_MAX)
+CILK_C_REDUCER_MIN_INSTANCE(unsigned short,     ushort,     USHRT_MAX)
+CILK_C_REDUCER_MIN_INSTANCE(int,                int,        INT_MAX)
+CILK_C_REDUCER_MIN_INSTANCE(unsigned int,       uint,       UINT_MAX)
+CILK_C_REDUCER_MIN_INSTANCE(unsigned int,       unsigned,   UINT_MAX) // alternate name
+CILK_C_REDUCER_MIN_INSTANCE(long,               long,       LONG_MAX)
+CILK_C_REDUCER_MIN_INSTANCE(unsigned long,      ulong,      ULONG_MAX)
+CILK_C_REDUCER_MIN_INSTANCE(long long,          longlong,   LLONG_MAX)
+CILK_C_REDUCER_MIN_INSTANCE(unsigned long long, ulonglong,  ULLONG_MAX)
+CILK_C_REDUCER_MIN_INSTANCE(float,              float,      HUGE_VALF)
+CILK_C_REDUCER_MIN_INSTANCE(double,             double,     HUGE_VAL)
+CILK_C_REDUCER_MIN_INSTANCE(long double,        longdouble, HUGE_VALL)
+__CILKRTS_END_EXTERN_C
+
+/// @endcond
+
+/** Min_index reducer type name.
+ *
+ *  This macro expands into the identifier which is the name of the min_index reducer
+ *  type for a specified numeric type.
+ *
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying the type of the
+ *              reducer.
+ *
+ *  @see @ref reducers_c_predefined
+ */
+#define CILK_C_REDUCER_MIN_INDEX_TYPE(tn)                                         \
+    __CILKRTS_MKIDENT(cilk_c_reducer_min_index_,tn)
+
+/** Declare an op_min_index reducer object.
+ *
+ *  This macro expands into a declaration of a min_index reducer object for a specified
+ *  numeric type. For example:
+ *
+ *      CILK_C_REDUCER_MIN_INDEX(my_reducer, double, -DBL_MIN_INDEX);
+ *
+ *  @param  obj The variable name to be used for the declared reducer object.
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying the type of the
+ *              reducer.
+ *  @param  v   The initial value for the reducer. (A value which can be assigned to the 
+ *              numeric type represented by @a tn.)
+ *
+ *  @see @ref reducers_c_predefined
+ */
+#define CILK_C_REDUCER_MIN_INDEX(obj,tn,v)                                        \
+    CILK_C_REDUCER_MIN_INDEX_TYPE(tn) obj =                                       \
+        CILK_C_INIT_REDUCER(_Typeof(obj.value),                             \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_min_index_reduce_,tn),   \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_min_index_identity_,tn), \
+                        __cilkrts_hyperobject_noop_destroy, {0, v})
+
+/** Minimize with a value.
+ *
+ *  `CILK_C_REDUCER_MIN_INDEX_CALC(reducer, i, v)` sets the current view of the
+ *  reducer to the min of its previous value and a specified new value.
+ *  This is equivalent to
+ *
+ *      REDUCER_VIEW(reducer) = min_index(REDUCER_VIEW(reducer), v)
+ *
+ *  If the value of the reducer is changed to @a v, then the index of the reducer is
+ *  changed to @a i. 
+ *
+ *  @param reducer  The reducer whose contained value and index are to be updated.
+ *  @param i        The index associated with the new value.
+ *  @param v        The value that it is to be minimized with.
+ */
+#define CILK_C_REDUCER_MIN_INDEX_CALC(reducer, i, v) do {                   \
+    _Typeof((reducer).value)* view = &(REDUCER_VIEW(reducer));              \
+    _Typeof(v) __value = (v);                                               \
+    if (view->value > __value) {                                            \
+        view->index = (i);                                                  \
+        view->value = __value;                                              \
+    } } while (0)
+
+/// @cond internal
+
+/** Declare the min_index view type.
+ *
+ *  The view of a min_index reducer is a structure containing both the
+ *  minimum value for the reducer and the index that was associated with
+ *  that value in the sequence of input values.
+ */
+#define CILK_C_REDUCER_MIN_INDEX_VIEW(t,tn)                                  \
+    typedef struct {                                                         \
+        __STDNS ptrdiff_t index;                                             \
+        t                 value;                                             \
+    } __CILKRTS_MKIDENT(cilk_c_reducer_min_index_view_,tn)
+
+/** Declare the min_index reducer functions for a numeric type.
+ *
+ *  This macro expands into external function declarations for functions which implement
+ *  the reducer functionality for the min_index reducer type for a specified numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer type name,
+ *              function names, etc.
+ */
+#define CILK_C_REDUCER_MIN_INDEX_DECLARATION(t,tn,id)                       \
+    CILK_C_REDUCER_MIN_INDEX_VIEW(t,tn);                                    \
+    typedef CILK_C_DECLARE_REDUCER(                                         \
+        __CILKRTS_MKIDENT(cilk_c_reducer_min_index_view_,tn))               \
+            CILK_C_REDUCER_MIN_INDEX_TYPE(tn);                              \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_min_index,tn,l,r);      \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_min_index,tn);
+/** Define the min_index reducer functions for a numeric type.
+ *
+ *  This macro expands into function definitions for functions which implement the
+ *  reducer functionality for the min_index reducer type for a specified numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer type name,
+ *              function names, etc.
+ */
+#define CILK_C_REDUCER_MIN_INDEX_DEFINITION(t,tn,id)                           \
+    CILK_C_REDUCER_MIN_INDEX_VIEW(t,tn);                                    \
+    typedef CILK_C_DECLARE_REDUCER(                                         \
+        __CILKRTS_MKIDENT(cilk_c_reducer_min_index_view_,tn))               \
+            CILK_C_REDUCER_MIN_INDEX_TYPE(tn);                              \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_min_index,tn,l,r)          \
+        { typedef __CILKRTS_MKIDENT(cilk_c_reducer_min_index_view_,tn) view_t; \
+          if (((view_t*)l)->value > ((view_t*)r)->value)                       \
+              *(view_t*)l = *(view_t*)r; }                                     \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_min_index,tn)            \
+        { typedef __CILKRTS_MKIDENT(cilk_c_reducer_min_index_view_,tn) view_t; \
+          ((view_t*)v)->index = 0; ((view_t*)v)->value = id; }
+//@{
+/** @def CILK_C_REDUCER_MIN_INDEX_INSTANCE 
+ *  @brief Declare or define implementation functions for a reducer type.
+ *
+ *  In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS` will be defined, and
+ *  this macro will generate reducer implementation functions. Everywhere else, `CILK_C_DEFINE_REDUCERS`
+ *  will be undefined, and this macro will expand into external declarations for the functions.
+ */
+#ifdef CILK_C_DEFINE_REDUCERS
+#   define CILK_C_REDUCER_MIN_INDEX_INSTANCE(t,tn,id)  \
+        CILK_C_REDUCER_MIN_INDEX_DEFINITION(t,tn,id)
+#else
+#   define CILK_C_REDUCER_MIN_INDEX_INSTANCE(t,tn,id)  \
+        CILK_C_REDUCER_MIN_INDEX_DECLARATION(t,tn,id)
+#endif
+//@}
+
+/*  Declare or define an instance of the reducer type and its functions for each 
+ *  numeric type.
+ */
+__CILKRTS_BEGIN_EXTERN_C
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(char,               char,       CHAR_MAX)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(unsigned char,      uchar,      CHAR_MAX)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(signed char,        schar,      SCHAR_MAX)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(wchar_t,            wchar_t,    WCHAR_MAX)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(short,              short,      SHRT_MAX)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(unsigned short,     ushort,     USHRT_MAX)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(int,                int,        INT_MAX)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(unsigned int,       uint,       UINT_MAX)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(unsigned int,       unsigned,   UINT_MAX) // alternate name
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(long,               long,       LONG_MAX)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(unsigned long,      ulong,      ULONG_MAX)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(long long,          longlong,   LLONG_MAX)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(unsigned long long, ulonglong,  ULLONG_MAX)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(float,              float,      HUGE_VALF)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(double,             double,     HUGE_VAL)
+CILK_C_REDUCER_MIN_INDEX_INSTANCE(long double,        longdouble, HUGE_VALL)
+__CILKRTS_END_EXTERN_C
+
+/// @endcond
+
+//@}
+
+#endif // defined REDUCER_MAX_H_INCLUDED
diff --git a/libcilkrts/include/cilk/reducer_opadd.h b/libcilkrts/include/cilk/reducer_opadd.h
new file mode 100644 (file)
index 0000000..4b7a83f
--- /dev/null
@@ -0,0 +1,690 @@
+/*  reducer_opadd.h                  -*- C++ -*-
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file reducer_opadd.h
+ *
+ *  @brief Defines classes for doing parallel addition reductions.
+ *
+ *  @ingroup ReducersAdd
+ *
+ *  @see ReducersAdd
+ */
+
+#ifndef REDUCER_OPADD_H_INCLUDED
+#define REDUCER_OPADD_H_INCLUDED
+
+#include <cilk/reducer.h>
+
+/** @defgroup ReducersAdd Addition Reducers
+ *
+ *  Addition reducers allow the computation of the sum of a set of values in
+ *  parallel.
+ *
+ *  @ingroup Reducers
+ *
+ *  You should be familiar with @ref pagereducers "Cilk reducers", described in
+ *  file `reducers.md`, and particularly with @ref reducers_using, before trying
+ *  to use the information in this file.
+ *
+ *  @section redopadd_usage Usage Example
+ *
+ *      cilk::reducer< cilk::op_add<int> > r;
+ *      cilk_for (int i = 0; i != N; ++i) {
+ *          *r += a[i];
+ *      }
+ *      return r.get_value();
+ *
+ *  @section redopadd_monoid The Monoid
+ *
+ *  @subsection redopadd_monoid_values Value Set
+ *
+ *  The value set of an addition reducer is the set of values of `Type`, which
+ *  is expected to be a builtin numeric type (or something like it, such as
+ *  `std::complex`).
+ *
+ *  @subsection redopadd_monoid_operator Operator
+ *
+ *  The operator of an addition reducer is the addition operator, defined by
+ *  the “`+`” binary operator on `Type`.
+ *
+ *  @subsection redopadd_monoid_identity Identity
+ *
+ *  The identity value of the reducer is the numeric value “`0`”. This is
+ *  expected to be the value of the default constructor `Type()`.
+ *
+ *  @section redopadd_operations Operations
+ *
+ *  @subsection redopadd_constructors Constructors
+ *
+ *      reducer()   // identity
+ *      reducer(const Type& value)
+ *      reducer(move_in(Type& variable))
+ *
+ *  @subsection redopadd_get_set Set and Get
+ *
+ *      r.set_value(const Type& value)
+ *      const Type& = r.get_value() const
+ *      r.move_in(Type& variable)
+ *      r.move_out(Type& variable)
+ *
+ *  @subsection redopadd_initial Initial Values
+ *
+ *  If an addition reducer is constructed without an explicit initial value,
+ *  then its initial value will be its identity value, as long as `Type`
+ *  satisfies the requirements of @ref redopadd_types.
+ *
+ *  @subsection redopadd_view_ops View Operations
+ *
+ *      *r += a
+ *      *r -= a
+ *      ++*r
+ *      --*r
+ *      (*r)++
+ *      (*r)--
+ *      *r = *r + a
+ *      *r = *r - a
+ *      *r = *r ± a1 ± a2 … ± an
+ *
+ *  The post-increment and post-decrement operations do not return a value. (If
+ *  they did, they would expose the value contained in the view, which is
+ *  non-deterministic in the middle of a reduction.)
+ *
+ *  Note that subtraction operations are allowed on an addition reducer because
+ *  subtraction is equivalent to addition with a negated operand. It is true
+ *  that `(x - y) - z` is not equivalent to `x - (y - z)`, but
+ *  `(x + (-y)) + (-z)` _is_ equivalent to `x + ((-y) + (-z))`.
+ *
+ *  @section redopadd_floating_point Issues with Floating-Point Types
+ *
+ *  Because of precision and round-off issues, floating-point addition is not
+ *  really associative. For example, `(1e30 + -1e30) + 1 == 1`, but 
+ *  `1e30 + (-1e30 + 1) == 0`.
+ *
+ *  In many cases, this won’t matter, but computations which have been
+ *  carefully ordered to control round-off errors may not deal well with
+ *  being reassociated. In general, you should be sure to understand the
+ *  floating-point behavior of your program before doing any transformation 
+ *  that will reassociate its computations. 
+ *
+ *  @section redopadd_types Type and Operator Requirements
+ *
+ *  `Type` must be `Copy Constructible`, `Default Constructible`, and
+ *  `Assignable`.
+ *
+ *  The operator “`+=`” must be defined on `Type`, with `x += a` having the
+ *  same meaning as `x = x + a`. In addition, if the code uses the “`-=`”,
+ *  pre-increment, post-increment, pre-decrement, or post-decrement operators,
+ *  then the corresponding operators must be defined on `Type`.
+ *
+ *  The expression `Type()` must be a valid expression which yields the
+ *  identity value (the value of `Type` whose numeric value is zero).
+ *
+ *  @section redopadd_in_c Addition Reducers in C
+ *
+ *  The @ref CILK_C_REDUCER_OPADD and @ref CILK_C_REDUCER_OPADD_TYPE macros can
+ *  be used to do addition reductions in C. For example:
+ *
+ *      CILK_C_REDUCER_OPADD(r, double, 0);
+ *      CILK_C_REGISTER_REDUCER(r);
+ *      cilk_for(int i = 0; i != n; ++i) {
+ *          REDUCER_VIEW(r) += a[i];
+ *      }
+ *      CILK_C_UNREGISTER_REDUCER(r);
+ *      printf("The sum of the elements of a is %f\n", REDUCER_VIEW(r));
+ *
+ *  See @ref reducers_c_predefined.
+ */
+
+#ifdef __cplusplus
+
+namespace cilk {
+
+/** The addition reducer view class.
+ *
+ *  This is the view class for reducers created with 
+ *  `cilk::reducer< cilk::op_add<Type> >`. It holds the accumulator variable 
+ *  for the reduction, and allows only addition and subtraction operations to 
+ *  be performed on it.
+ *
+ *  @note   The reducer “dereference” operation (`reducer::operator *()`) 
+ *          yields a reference to the view. Thus, for example, the view class’s
+ *          `+=` operation would be used in an expression like `*r += a`, where
+ *          `r` is an op_add reducer variable.
+ *
+ *  @tparam Type    The type of the contained accumulator variable. This will 
+ *                  be the value type of a monoid_with_view that is 
+ *                  instantiated with this view.
+ *
+ *  @see ReducersAdd
+ *  @see op_add
+ *
+ *  @ingroup ReducersAdd
+ */
+template <typename Type>
+class op_add_view : public scalar_view<Type>
+{
+    typedef scalar_view<Type> base;
+    
+public:
+    /** Class to represent the right-hand side of 
+     *  `*reducer = *reducer ± value`.
+     *
+     *  The only assignment operator for the op_add_view class takes an
+     *  rhs_proxy as its operand. This results in the syntactic restriction
+     *  that the only expressions that can be assigned to an op_add_view are
+     *  ones which generate an rhs_proxy — that is, expressions of the form
+     *  `op_add_view ± value ... ± value`.
+     *
+     *  @warning
+     *  The lhs and rhs views in such an assignment must be the same; 
+     *  otherwise, the behavior will be undefined. (I.e., `v1 = v1 + x` is
+     *  legal; `v1 = v2 + x` is illegal.) This condition will be checked with a
+     *  runtime assertion when compiled in debug mode.
+     *
+     *  @see op_add_view
+     */
+    class rhs_proxy {
+        friend class op_add_view;
+
+        const op_add_view* m_view;
+        Type               m_value;
+
+        // Constructor is invoked only from op_add_view::operator+() and 
+        // op_add_view::operator-().
+        //
+        rhs_proxy(const op_add_view* view, const Type& value) :
+            m_view(view), m_value(value) {}
+
+        rhs_proxy& operator=(const rhs_proxy&); // Disable assignment operator
+        rhs_proxy();                            // Disable default constructor
+
+    public:
+        //@{
+        /** Add or subtract an additional rhs value. If `v` is an op_add_view
+         *  and `a1` is a value, then the expression `v + a1` invokes the view’s
+         *  `operator+()` to create an rhs_proxy for `(v, a1)`; then 
+         *  `v + a1 + a2` invokes the rhs_proxy’s `operator+()` to create a new
+         *  rhs_proxy for `(v, a1+a2)`. This allows the right-hand side of an
+         *  assignment to be not just `view ± value`, but 
+         *  `view ± value ± value ... ± value`. The effect is that
+         *
+         *      v = v ± a1 ± a2 ... ± an;
+         *
+         *  is evaluated as
+         *
+         *      v = v ± (±a1 ± a2 ... ± an);
+         */
+        rhs_proxy& operator+(const Type& x) { m_value += x; return *this; }
+        rhs_proxy& operator-(const Type& x) { m_value -= x; return *this; }
+        //@}
+    };
+
+    
+    /** Default/identity constructor. This constructor initializes the 
+     *  contained value to `Type()`, which is expected to be the identity value
+     *  for addition on `Type`.
+     */
+    op_add_view() : base() {}
+
+    /** Construct with a specified initial value.
+     */
+    explicit op_add_view(const Type& v) : base(v) {}
+    
+    /** Reduction operation.
+     *
+     *  This function is invoked by the @ref op_add monoid to combine the views
+     *  of two strands when the right strand merges with the left one. It adds
+     *  the value contained in the right-strand view to the value contained in
+     *  the left-strand view, and leaves the value in the right-strand view
+     *  undefined.
+     *
+     *  @param  right   A pointer to the right-strand view. (`this` points to
+     *                  the left-strand view.)
+     *
+     *  @note   Used only by the @ref op_add monoid to implement the monoid
+     *          reduce operation.
+     */
+    void reduce(op_add_view* right) { this->m_value += right->m_value; }
+
+    /** @name Accumulator variable updates.
+     *
+     *  These functions support the various syntaxes for incrementing or
+     *  decrementing the accumulator variable contained in the view.
+     */
+    //@{
+
+    /** Increment the accumulator variable by @a x.
+     */
+    op_add_view& operator+=(const Type& x) { this->m_value += x; return *this; }
+
+    /** Decrement the accumulator variable by @a x.
+     */
+    op_add_view& operator-=(const Type& x) { this->m_value -= x; return *this; }
+
+    /** Pre-increment.
+     */
+    op_add_view& operator++() { ++this->m_value; return *this; }
+
+    /** Post-increment.
+     *
+     *  @note   Conventionally, post-increment operators return the old value
+     *          of the incremented variable. However, reducer views do not
+     *          expose their contained values, so `view++` does not have a
+     *          return value.
+     */
+    void operator++(int) { this->m_value++; }
+
+    /** Pre-decrement.
+     */
+    op_add_view& operator--() { --this->m_value; return *this; }
+
+    /** Post-decrement.
+     *
+     *  @note   Conventionally, post-decrement operators return the old value
+     *          of the decremented variable. However, reducer views do not
+     *          expose their contained values, so `view--` does not have a
+     *          return value.
+     */
+    void operator--(int) { this->m_value--; }
+
+    /** Create an object representing `*this + x`.
+     *
+     *  @see rhs_proxy
+     */
+    rhs_proxy operator+(const Type& x) const { return rhs_proxy(this, x); }
+
+    /** Create an object representing `*this - x`.
+     *
+     *  @see rhs_proxy
+     */
+    rhs_proxy operator-(const Type& x) const { return rhs_proxy(this, -x); }
+
+    /** Assign the result of a `view ± value` expression to the view. Note that
+     *  this is the only assignment operator for this class.
+     *
+     *  @see rhs_proxy
+     */
+    op_add_view& operator=(const rhs_proxy& rhs) {
+        __CILKRTS_ASSERT(this == rhs.m_view);
+        this->m_value += rhs.m_value;
+        return *this;
+    }
+    
+    //@}
+};
+
+
+/** Monoid class for addition reductions. Instantiate the cilk::reducer 
+ *  template class with an op_add monoid to create an addition reducer class.
+ *  For example, to compute
+ *  the sum of a set of `int` values:
+ *
+ *      cilk::reducer< cilk::op_add<int> > r;
+ *
+ *  @tparam Type    The reducer value type.
+ *  @tparam Align   If `false` (the default), reducers instantiated on this
+ *                  monoid will be naturally aligned (the Cilk library 1.0
+ *                  behavior). If `true`, reducers instantiated on this monoid
+ *                  will be cache-aligned for binary compatibility with 
+ *                  reducers in Cilk library version 0.9.
+ *
+ *  @see ReducersAdd
+ *  @see op_add_view
+ *
+ *  @ingroup ReducersAdd
+ */
+template <typename Type, bool Align = false>
+struct op_add : public monoid_with_view<op_add_view<Type>, Align> {};
+
+/** **Deprecated** addition reducer wrapper class.
+ *
+ *  reducer_opadd is the same as @ref reducer<@ref op_add>, except that
+ *  reducer_opadd is a proxy for the contained view, so that accumulator
+ *  variable update operations can be applied directly to the reducer. For
+ *  example, a value is added to a `reducer<%op_add>` with `*r += a`, but a
+ *  value can be added to a `%reducer_opadd` with `r += a`.
+ *
+ *  @deprecated Users are strongly encouraged to use `reducer<monoid>`
+ *              reducers rather than the old wrappers like reducer_opadd. 
+ *              The `reducer<monoid>` reducers show the reducer/monoid/view
+ *              architecture more clearly, are more consistent in their
+ *              implementation, and present a simpler model for new
+ *              user-implemented reducers.
+ *
+ *  @note   Implicit conversions are provided between `%reducer_opadd` 
+ *          and `reducer<%op_add>`. This allows incremental code
+ *          conversion: old code that used `%reducer_opadd` can pass a
+ *          `%reducer_opadd` to a converted function that now expects a
+ *          pointer or reference to a `reducer<%op_add>`, and vice
+ *          versa.
+ *
+ *  @tparam Type    The value type of the reducer.
+ *
+ *  @see op_add
+ *  @see reducer
+ *  @see ReducersAdd
+ *
+ *  @ingroup ReducersAdd
+ */
+template <typename Type>
+class reducer_opadd : public reducer< op_add<Type, true> >
+{
+    typedef reducer< op_add<Type, true> > base;
+    using base::view;
+
+  public:
+    /// The view type for the reducer.
+    typedef typename base::view_type        view_type;
+    
+    /// The view’s rhs proxy type.
+    typedef typename view_type::rhs_proxy   rhs_proxy;
+
+    /// The view type for the reducer.
+    typedef view_type                       View;
+
+    /// The monoid type for the reducer.
+    typedef typename base::monoid_type      Monoid;
+
+    /** @name Constructors
+     */
+    //@{
+    
+    /** Default (identity) constructor.
+     *
+     * Constructs the wrapper with the default initial value of `Type()`.
+     */
+    reducer_opadd() {}
+
+    /** Value constructor.
+     *
+     *  Constructs the wrapper with a specified initial value.
+     */
+    explicit reducer_opadd(const Type& initial_value) : base(initial_value) {}
+    
+    //@}
+
+    /** @name Forwarded functions
+     *  @details Functions that update the contained accumulator variable are
+     *  simply forwarded to the contained @ref op_add_view. */
+    //@{
+    
+    /// @copydoc op_add_view::operator+=(const Type&)
+    reducer_opadd& operator+=(const Type& x)    { view() += x; return *this; }
+    
+    /// @copydoc op_add_view::operator-=(const Type&)
+    reducer_opadd& operator-=(const Type& x)    { view() -= x; return *this; }
+    
+    /// @copydoc op_add_view::operator++()
+    reducer_opadd& operator++()                 { ++view(); return *this; }
+    
+    /// @copydoc op_add_view::operator++(int)
+    void operator++(int)                        { view()++; }
+    
+    /// @copydoc op_add_view::operator-\-()
+    reducer_opadd& operator--()                 { --view(); return *this; }
+    
+    /// @copydoc op_add_view::operator-\-(int)
+    void operator--(int)                        { view()--; }
+
+    // The legacy definitions of reducer_opadd::operator+() and
+    // reducer_opadd::operator-() have different behavior and a different
+    // return type than this definition. The legacy version is defined as a
+    // member function, so this new version is defined as a free function to
+    // give it a different signature, so that they won’t end up sharing a
+    // single object file entry.
+
+    /// @copydoc op_add_view::operator+(const Type&) const
+    friend rhs_proxy operator+(const reducer_opadd& r, const Type& x)
+    { 
+        return r.view() + x; 
+    }
+    /// @copydoc op_add_view::operator-(const Type&) const
+    friend rhs_proxy operator-(const reducer_opadd& r, const Type& x)
+    { 
+        return r.view() - x; 
+    }
+    /// @copydoc op_add_view::operator=(const rhs_proxy&)
+    reducer_opadd& operator=(const rhs_proxy& temp) 
+    {
+        view() = temp;
+        return *this; 
+    }
+    //@}
+
+    /** @name Dereference
+     *  @details Dereferencing a wrapper is a no-op. It simply returns the
+     *  wrapper. Combined with the rule that the wrapper forwards view
+     *  operations to its contained view, this means that view operations can
+     *  be written the same way on reducers and wrappers, which is convenient
+     *  for incrementally converting old code using wrappers to use reducers
+     *  instead. That is:
+     *
+     *      reducer< op_add<int> > r;
+     *      *r += a;    // *r returns the view
+     *                  // operator += is a view member function
+     *
+     *      reducer_opadd<int> w;
+     *      *w += a;    // *w returns the wrapper
+     *                  // operator += is a wrapper member function that
+     *                  // calls the corresponding view function
+     */
+    //@{
+    reducer_opadd&       operator*()       { return *this; }
+    reducer_opadd const& operator*() const { return *this; }
+
+    reducer_opadd*       operator->()       { return this; }
+    reducer_opadd const* operator->() const { return this; }
+    //@}
+    
+    /** @name Upcast
+     *  @details In Cilk library 0.9, reducers were always cache-aligned. In
+     *  library  1.0, reducer cache alignment is optional. By default, reducers
+     *  are unaligned (i.e., just naturally aligned), but legacy wrappers
+     *  inherit from cache-aligned reducers for binary compatibility.
+     *
+     *  This means that a wrapper will automatically be upcast to its aligned
+     *  reducer base class. The following conversion operators provide
+     *  pseudo-upcasts to the corresponding unaligned reducer class.
+     */
+    //@{
+    operator reducer< op_add<Type, false> >& ()
+    {
+        return *reinterpret_cast< reducer< op_add<Type, false> >* >(this);
+    }
+    operator const reducer< op_add<Type, false> >& () const
+    {
+        return *reinterpret_cast< const reducer< op_add<Type, false> >* >(this);
+    }
+    //@}
+};
+
+/// @cond internal
+/** Metafunction specialization for reducer conversion.
+ *
+ *  This specialization of the @ref legacy_reducer_downcast template class 
+ *  defined in reducer.h causes the `reducer< op_add<Type> >` class to have an 
+ *  `operator reducer_opadd<Type>& ()` conversion operator that statically 
+ *  downcasts the `reducer<op_add>` to the corresponding `reducer_opadd` type.
+ *  (The reverse conversion, from `reducer_opadd` to `reducer<op_add>`, is just
+ *  an upcast, which is provided for free by the language.)
+ *
+ *  @ingroup ReducersAdd
+ */
+template <typename Type, bool Align>
+struct legacy_reducer_downcast<reducer<op_add<Type, Align> > >
+{
+    typedef reducer_opadd<Type> type;
+};
+/// @endcond
+
+} // namespace cilk
+
+#endif // __cplusplus
+
+
+/** @ingroup ReducersAdd
+ */
+//@{
+
+/** @name C Language Reducer Macros
+ *
+ *  These macros are used to declare and work with numeric op_add reducers in 
+ *  C code.
+ *
+ *  @see @ref page_reducers_in_c
+ */
+ //@{
+__CILKRTS_BEGIN_EXTERN_C
+
+/** Opadd reducer type name.
+ *
+ *  This macro expands into the identifier which is the name of the op_add
+ *  reducer type for a specified numeric type.
+ *
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying
+ *              the type of the reducer.
+ *
+ *  @see @ref reducers_c_predefined
+ *  @see ReducersAdd
+ */
+#define CILK_C_REDUCER_OPADD_TYPE(tn)                                         \
+    __CILKRTS_MKIDENT(cilk_c_reducer_opadd_,tn)
+
+/** Declare an op_add reducer object.
+ *
+ *  This macro expands into a declaration of an op_add reducer object for a
+ *  specified numeric type. For example:
+ *
+ *      CILK_C_REDUCER_OPADD(my_reducer, double, 0.0);
+ *
+ *  @param  obj The variable name to be used for the declared reducer object.
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying
+ *              the type of the reducer.
+ *  @param  v   The initial value for the reducer. (A value which can be
+ *              assigned to the numeric type represented by @a tn.)
+ *
+ *  @see @ref reducers_c_predefined
+ *  @see ReducersAdd
+ */
+#define CILK_C_REDUCER_OPADD(obj,tn,v)                                        \
+    CILK_C_REDUCER_OPADD_TYPE(tn) obj =                                       \
+        CILK_C_INIT_REDUCER(_Typeof(obj.value),                               \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_opadd_reduce_,tn),   \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_opadd_identity_,tn), \
+                        __cilkrts_hyperobject_noop_destroy, v)
+
+/// @cond internal
+
+/** Declare the op_add reducer functions for a numeric type.
+ *
+ *  This macro expands into external function declarations for functions which
+ *  implement the reducer functionality for the op_add reducer type for a
+ *  specified numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer
+ *              type name, function names, etc.
+ */
+#define CILK_C_REDUCER_OPADD_DECLARATION(t,tn)                             \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPADD_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opadd,tn,l,r);         \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opadd,tn);
+/** Define the op_add reducer functions for a numeric type.
+ *
+ *  This macro expands into function definitions for functions which implement
+ *  the reducer functionality for the op_add reducer type for a specified
+ *  numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer
+ *              type name, function names, etc.
+ */
+#define CILK_C_REDUCER_OPADD_DEFINITION(t,tn)                              \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPADD_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opadd,tn,l,r)          \
+        { *(t*)l += *(t*)r; }                                              \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opadd,tn)            \
+        { *(t*)v = 0; }
+//@{
+/** @def CILK_C_REDUCER_OPADD_INSTANCE 
+ *  @brief Declare or define implementation functions for a reducer type.
+ *
+ *  In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS`
+ *  will be defined, and this macro will generate reducer implementation 
+ *  functions. Everywhere else, `CILK_C_DEFINE_REDUCERS` will be undefined,
+ *  and this macro will expand into external declarations for the functions.
+ */
+#ifdef CILK_C_DEFINE_REDUCERS
+#   define CILK_C_REDUCER_OPADD_INSTANCE(t,tn)  \
+        CILK_C_REDUCER_OPADD_DEFINITION(t,tn)
+#else
+#   define CILK_C_REDUCER_OPADD_INSTANCE(t,tn)  \
+        CILK_C_REDUCER_OPADD_DECLARATION(t,tn)
+#endif
+//@}
+
+/*  Declare or define an instance of the reducer type and its functions for each 
+ *  numeric type.
+ */
+CILK_C_REDUCER_OPADD_INSTANCE(char,                 char)
+CILK_C_REDUCER_OPADD_INSTANCE(unsigned char,        uchar)
+CILK_C_REDUCER_OPADD_INSTANCE(signed char,          schar)
+CILK_C_REDUCER_OPADD_INSTANCE(wchar_t,              wchar_t)
+CILK_C_REDUCER_OPADD_INSTANCE(short,                short)
+CILK_C_REDUCER_OPADD_INSTANCE(unsigned short,       ushort)
+CILK_C_REDUCER_OPADD_INSTANCE(int,                  int)
+CILK_C_REDUCER_OPADD_INSTANCE(unsigned int,         uint)
+CILK_C_REDUCER_OPADD_INSTANCE(unsigned int,         unsigned) /* alternate name */
+CILK_C_REDUCER_OPADD_INSTANCE(long,                 long)
+CILK_C_REDUCER_OPADD_INSTANCE(unsigned long,        ulong)
+CILK_C_REDUCER_OPADD_INSTANCE(long long,            longlong)
+CILK_C_REDUCER_OPADD_INSTANCE(unsigned long long,   ulonglong)
+CILK_C_REDUCER_OPADD_INSTANCE(float,                float)
+CILK_C_REDUCER_OPADD_INSTANCE(double,               double)
+CILK_C_REDUCER_OPADD_INSTANCE(long double,          longdouble)
+
+//@endcond
+
+__CILKRTS_END_EXTERN_C
+
+//@}
+
+//@}
+
+#endif /*  REDUCER_OPADD_H_INCLUDED */
diff --git a/libcilkrts/include/cilk/reducer_opand.h b/libcilkrts/include/cilk/reducer_opand.h
new file mode 100644 (file)
index 0000000..8a086c9
--- /dev/null
@@ -0,0 +1,604 @@
+/*  reducer_opand.h                  -*- C++ -*-
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file reducer_opand.h
+ *
+ *  @brief Defines classes for doing parallel bitwise and reductions.
+ *
+ *  @ingroup ReducersAnd
+ *
+ *  @see ReducersAnd
+ */
+
+#ifndef REDUCER_OPAND_H_INCLUDED
+#define REDUCER_OPAND_H_INCLUDED
+
+#include <cilk/reducer.h>
+
+/** @defgroup ReducersAnd Bitwise And Reducers
+ *
+ *  Bitwise and reducers allow the computation of the bitwise and of a set of
+ *  values in parallel.
+ *
+ *  @ingroup Reducers
+ *
+ *  You should be familiar with @ref pagereducers "Cilk reducers", described in
+ *  file `reducers.md`, and particularly with @ref reducers_using, before trying
+ *  to use the information in this file.
+ *
+ *  @section redopand_usage Usage Example
+ *
+ *      cilk::reducer< cilk::op_and<unsigned> > r;
+ *      cilk_for (int i = 0; i != N; ++i) {
+ *          *r &= a[i];
+ *      }
+ *      unsigned result;
+ *      r.move_out(result);
+ *
+ *  @section redopand_monoid The Monoid
+ *
+ *  @subsection redopand_monoid_values Value Set
+ *
+ *  The value set of a bitwise and reducer is the set of values of `Type`, 
+ *  which is expected to be a builtin integer type which has a representation
+ *  as a sequence of bits (or something like it, such as `bool` or
+ *  `std::bitset`).
+ *
+ *  @subsection redopand_monoid_operator Operator
+ *
+ *  The operator of a bitwise and reducer is the bitwise and operator, defined
+ *  by the “`&`” binary operator on `Type`.
+ *
+ *  @subsection redopand_monoid_identity Identity
+ *
+ *  The identity value of the reducer is the value whose representation 
+ *  contains all 1-bits. This is expected to be the value of the expression
+ *  `~Type()` (i.e., the bitwise negation operator applied to the default value
+ *  of the value type).
+ *
+ *  @section redopand_operations Operations
+ *
+ *  @subsection redopand_constructors Constructors
+ *
+ *      reducer()   // identity
+ *      reducer(const Type& value)
+ *      reducer(move_in(Type& variable))
+ *
+ *  @subsection redopand_get_set Set and Get
+ *
+ *      r.set_value(const Type& value)
+ *      const Type& = r.get_value() const
+ *      r.move_in(Type& variable)
+ *      r.move_out(Type& variable)
+ *
+ *  @subsection redopand_initial Initial Values
+ *
+ *  If a bitwise and reducer is constructed without an explicit initial value,
+ *  then its initial value will be its identity value, as long as `Type`
+ *  satisfies the requirements of @ref redopand_types.
+ *
+ *  @subsection redopand_view_ops View Operations
+ *
+ *      *r &= a
+ *      *r = *r & a
+ *      *r = *r & a1 & a2 … & an
+ *
+ *  @section redopand_types Type and Operator Requirements
+ *
+ *  `Type` must be `Copy Constructible`, `Default Constructible`, and
+ *  `Assignable`.
+ *
+ *  The operator “`&=`” must be defined on `Type`, with `x &= a` having the 
+ *  same meaning as `x = x & a`.
+ *
+ *  The expression `~ Type()` must be a valid expression which yields the
+ *  identity value (the value of `Type` whose representation consists of all
+ *  1-bits).
+ *
+ *  @section redopand_in_c Bitwise And Reducers in C
+ *
+ *  The @ref CILK_C_REDUCER_OPAND and @ref CILK_C_REDUCER_OPAND_TYPE macros can
+ *  be used to do bitwise and reductions in C. For example:
+ *
+ *      CILK_C_REDUCER_OPAND(r, uint, ~0);
+ *      CILK_C_REGISTER_REDUCER(r);
+ *      cilk_for(int i = 0; i != n; ++i) {
+ *          REDUCER_VIEW(r) &= a[i];
+ *      }
+ *      CILK_C_UNREGISTER_REDUCER(r);
+ *      printf("The bitwise AND of the elements of a is %x\n", REDUCER_VIEW(r));
+ *
+ *  See @ref reducers_c_predefined.
+ */
+
+#ifdef __cplusplus
+
+namespace cilk {
+
+/** The bitwise and reducer view class.
+ *
+ *  This is the view class for reducers created with 
+ *  `cilk::reducer< cilk::op_and<Type> >`. It holds the accumulator variable 
+ *  for the reduction, and allows only `and` operations to be performed on it.
+ *
+ *  @note   The reducer “dereference” operation (`reducer::operator *()`)
+ *          yields a reference to the view. Thus, for example, the view class’s
+ *          `&=` operation would be used in an expression like `*r &= a`, where
+ *          `r` is an opmod reducer variable.
+ *
+ *  @tparam Type    The type of the contained accumulator variable. This will
+ *                  be the value type of a monoid_with_view that is
+ *                  instantiated with this view.
+ *
+ *  @see ReducersAnd
+ *  @see op_and
+ *
+ *  @ingroup ReducersAnd
+ */
+template <typename Type>
+class op_and_view : public scalar_view<Type>
+{
+    typedef scalar_view<Type> base;
+    
+public:
+    /** Class to represent the right-hand side of `*reducer = *reducer & value`.
+     *
+     *  The only assignment operator for the op_and_view class takes an
+     *  rhs_proxy as its operand. This results in the syntactic restriction 
+     *  that the only expressions that can be assigned to an op_and_view are
+     *  ones which generate an rhs_proxy — that is, expressions of the form
+     *  `op_and_view & value ... & value`.
+     *
+     *  @warning
+     *  The lhs and rhs views in such an assignment must be the same; 
+     *  otherwise, the behavior will be undefined. (I.e., `v1 = v1 & x` is
+     *  legal; `v1 = v2 & x` is illegal.)  This condition will be checked with
+     *  a runtime assertion when compiled in debug mode.
+     *
+     *  @see op_and_view
+     */
+    class rhs_proxy {
+    private:
+        friend class op_and_view;
+
+        const op_and_view* m_view;
+        Type               m_value;
+
+        // Constructor is invoked only from op_and_view::operator&().
+        //
+        rhs_proxy(const op_and_view* view, const Type& value) : m_view(view), m_value(value) {}
+
+        rhs_proxy& operator=(const rhs_proxy&); // Disable assignment operator
+        rhs_proxy();                            // Disable default constructor
+
+    public:
+        /** Bitwise and with an additional rhs value. If `v` is an op_and_view
+         *  and `a1` is a value, then the expression `v & a1` invokes the
+         *  view’s `operator&()` to create an rhs_proxy for `(v, a1)`; then
+         *  `v & a1 & a2` invokes the rhs_proxy’s `operator&()` to create a new
+         *  rhs_proxy for `(v, a1&a2)`. This allows the right-hand side of an
+         *  assignment to be not just `view & value`, but 
+         *  `view & value & value ... & value`. The effect is that
+         *
+         *      v = v & a1 & a2 ... & an;
+         *
+         *  is evaluated as
+         *
+         *      v = v & (a1 & a2 ... & an);
+         */
+        rhs_proxy& operator&(const Type& x) { m_value &= x; return *this; }
+    };
+
+
+    /** Default/identity constructor. This constructor initializes the
+     *  contained value to `~ Type()`.
+     */
+    op_and_view() : base(~Type()) {}
+
+    /** Construct with a specified initial value.
+     */
+    explicit op_and_view(const Type& v) : base(v) {}
+    
+    
+    /** Reduction operation.
+     *
+     *  This function is invoked by the @ref op_and monoid to combine the views
+     *  of two strands when the right strand merges with the left one. It
+     *  “ands” the value contained in the left-strand view with the value
+     *  contained in the right-strand view, and leaves the value in the
+     *  right-strand view undefined.
+     *
+     *  @param  right   A pointer to the right-strand view. (`this` points to
+     *                  the left-strand view.)
+     *
+     *  @note   Used only by the @ref op_and monoid to implement the monoid
+     *          reduce operation.
+     */
+    void reduce(op_and_view* right) { this->m_value &= right->m_value; }
+    
+    /** @name Accumulator variable updates.
+     *
+     *  These functions support the various syntaxes for “anding” the
+     *  accumulator variable contained in the view with some value.
+     */
+    //@{
+
+    /** And the accumulator variable with @a x.
+     */
+    op_and_view& operator&=(const Type& x) { this->m_value &= x; return *this; }
+
+    /** Create an object representing `*this & x`.
+     *
+     *  @see rhs_proxy
+     */
+    rhs_proxy operator&(const Type& x) const { return rhs_proxy(this, x); }
+
+    /** Assign the result of a `view & value` expression to the view. Note that
+     *  this is the only assignment operator for this class.
+     *
+     *  @see rhs_proxy
+     */
+    op_and_view& operator=(const rhs_proxy& rhs) {
+        __CILKRTS_ASSERT(this == rhs.m_view);
+        this->m_value &= rhs.m_value;
+        return *this;
+    }
+    
+    //@}
+};
+
+/** Monoid class for bitwise and reductions. Instantiate the cilk::reducer
+ *  template class with an op_and monoid to create a bitwise and reducer
+ *  class. For example, to compute the bitwise and of a set of `unsigned long`
+ *  values:
+ *
+ *      cilk::reducer< cilk::op_and<unsigned long> > r;
+ *
+ *  @tparam Type    The reducer value type.
+ *  @tparam Align   If `false` (the default), reducers instantiated on this
+ *                  monoid will be naturally aligned (the Cilk library 1.0
+ *                  behavior). If `true`, reducers instantiated on this monoid
+ *                  will be cache-aligned for binary compatibility with 
+ *                  reducers in Cilk library version 0.9.
+ *
+ *  @see ReducersAnd
+ *  @see op_and_view
+ *
+ *  @ingroup ReducersAnd
+ */
+template <typename Type, bool Align = false>
+struct op_and : public monoid_with_view<op_and_view<Type>, Align> {};
+
+/** Deprecated bitwise and reducer class.
+ *
+ *  reducer_opand is the same as @ref reducer<@ref op_and>, except that
+ *  reducer_opand is a proxy for the contained view, so that accumulator
+ *  variable update operations can be applied directly to the reducer. For
+ *  example, a value is anded with  a `reducer<%op_and>` with `*r &= a`, but a
+ *  value can be anded with a `%reducer_opand` with `r &= a`.
+ *
+ *  @deprecated Users are strongly encouraged to use `reducer<monoid>`
+ *              reducers rather than the old wrappers like reducer_opand. 
+ *              The `reducer<monoid>` reducers show the reducer/monoid/view
+ *              architecture more clearly, are more consistent in their
+ *              implementation, and present a simpler model for new
+ *              user-implemented reducers.
+ *
+ *  @note   Implicit conversions are provided between `%reducer_opand` 
+ *          and `reducer<%op_and>`. This allows incremental code
+ *          conversion: old code that used `%reducer_opand` can pass a
+ *          `%reducer_opand` to a converted function that now expects a
+ *          pointer or reference to a `reducer<%op_and>`, and vice
+ *          versa.
+ *
+ *  @tparam Type    The value type of the reducer.
+ *
+ *  @see op_and
+ *  @see reducer
+ *  @see ReducersAnd
+ *
+ *  @ingroup ReducersAnd
+ */
+template <typename Type>
+class reducer_opand : public reducer< op_and<Type, true> >
+{
+    typedef reducer< op_and<Type, true> > base;
+    using base::view;
+
+public:
+    /// The view type for the reducer.
+    typedef typename base::view_type        view_type;
+    
+    /// The view’s rhs proxy type.
+    typedef typename view_type::rhs_proxy   rhs_proxy;
+    
+    /// The view type for the reducer.
+    typedef view_type                       View;
+
+    /// The monoid type for the reducer.
+    typedef typename base::monoid_type      Monoid;
+    
+    /** @name Constructors
+     */
+    //@{
+    
+    /** Default constructor.
+     *
+     *  Constructs the wrapper with the default initial value of `Type()`
+     *  (not the identity value).
+     */
+    reducer_opand() : base(Type()) {}
+
+    /** Value constructor.
+     *
+     *  Constructs the wrapper with a specified initial value.
+     */
+    explicit reducer_opand(const Type& initial_value) : base(initial_value) {}
+    
+    //@}
+
+    /** @name Forwarded functions
+     *  @details Functions that update the contained accumulator variable are
+     *  simply forwarded to the contained @ref op_and_view. */
+    //@{
+
+    /// @copydoc op_and_view::operator&=(const Type&)
+    reducer_opand& operator&=(const Type& x)
+    {
+        view() &= x;
+        return *this;
+    }
+    
+    // The legacy definition of reducer_opand::operator&() has different
+    // behavior and a different return type than this definition. The legacy
+    // version is defined as a member function, so this new version is defined
+    // as a free function to give it a different signature, so that they won’t 
+    // end up sharing a single object file entry.
+    
+    /// @copydoc op_and_view::operator&(const Type&) const
+    friend rhs_proxy operator&(const reducer_opand& r, const Type& x)
+    { 
+        return r.view() & x; 
+    }
+
+    /// @copydoc op_and_view::operator=(const rhs_proxy&)
+    reducer_opand& operator=(const rhs_proxy& temp) 
+    { 
+        view() = temp;
+        return *this; 
+    }
+    //@}
+
+    /** @name Dereference
+     *  @details Dereferencing a wrapper is a no-op. It simply returns the
+     *  wrapper. Combined with the rule that the wrapper forwards view
+     *  operations to its contained view, this means that view operations can
+     *  be written the same way on reducers and wrappers, which is convenient
+     *  for incrementally converting old code using wrappers to use reducers
+     *  instead. That is:
+     *
+     *      reducer< op_and<int> > r;
+     *      *r &= a;    // *r returns the view
+     *                  // operator &= is a view member function
+     *
+     *      reducer_opand<int> w;
+     *      *w &= a;    // *w returns the wrapper
+     *                  // operator &= is a wrapper member function that
+     *                  // calls the corresponding view function
+     */
+    //@{
+    reducer_opand&       operator*()       { return *this; }
+    reducer_opand const& operator*() const { return *this; }
+
+    reducer_opand*       operator->()       { return this; }
+    reducer_opand const* operator->() const { return this; }
+    //@}
+    
+    /** @name Upcast
+     *  @details In Cilk library 0.9, reducers were always cache-aligned. In
+     *  library  1.0, reducer cache alignment is optional. By default, reducers
+     *  are unaligned (i.e., just naturally aligned), but legacy wrappers
+     *  inherit from cache-aligned reducers for binary compatibility.
+     *
+     *  This means that a wrapper will automatically be upcast to its aligned
+     *  reducer base class. The following conversion operators provide
+     *  pseudo-upcasts to the corresponding unaligned reducer class.
+     */
+    //@{
+    operator reducer< op_and<Type, false> >& ()
+    {
+        return *reinterpret_cast< reducer< op_and<Type, false> >* >(this);
+    }
+    operator const reducer< op_and<Type, false> >& () const
+    {
+        return *reinterpret_cast< const reducer< op_and<Type, false> >* >(this);
+    }
+    //@}
+};
+
+/// @cond internal
+/** Metafunction specialization for reducer conversion.
+ *
+ *  This specialization of the @ref legacy_reducer_downcast template class 
+ *  defined in reducer.h causes the `reducer< op_and<Type> >` class to have an 
+ *  `operator reducer_opand<Type>& ()` conversion operator that statically
+ *  downcasts the `reducer<op_and>` to the corresponding `reducer_opand` type.
+ *  (The reverse conversion, from `reducer_opand` to `reducer<op_and>`, is just
+ *  an upcast, which is provided for free by the language.)
+ *
+ *  @ingroup ReducersAnd
+ */
+template <typename Type, bool Align>
+struct legacy_reducer_downcast<reducer<op_and<Type, Align> > >
+{
+    typedef reducer_opand<Type> type;
+};
+/// @endcond
+
+} // namespace cilk
+
+#endif // __cplusplus
+
+
+/** @ingroup ReducersAdd
+ */
+//@{
+
+/** @name C language reducer macros
+ *
+ *  These macros are used to declare and work with op_and reducers in C code.
+ *
+ *  @see @ref page_reducers_in_c
+ */
+ //@{
+__CILKRTS_BEGIN_EXTERN_C
+
+/** Opand reducer type name.
+ *
+ *  This macro expands into the identifier which is the name of the op_and 
+ *  reducer type for a specified numeric type.
+ *
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying
+ *              the type of the reducer.
+ *
+ *  @see @ref reducers_c_predefined
+ *  @see ReducersAnd
+ */
+#define CILK_C_REDUCER_OPAND_TYPE(tn)                                         \
+    __CILKRTS_MKIDENT(cilk_c_reducer_opand_,tn)
+
+/** Declare an op_and reducer object.
+ *
+ *  This macro expands into a declaration of an op_and reducer object for a
+ *  specified numeric type. For example:
+ *
+ *      CILK_C_REDUCER_OPAND(my_reducer, ulong, ~0UL);
+ *
+ *  @param  obj The variable name to be used for the declared reducer object.
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying
+ *              the type of the reducer.
+ *  @param  v   The initial value for the reducer. (A value which can be
+ *              assigned to the numeric type represented by @a tn.)
+ *
+ *  @see @ref reducers_c_predefined
+ *  @see ReducersAnd
+ */
+#define CILK_C_REDUCER_OPAND(obj,tn,v)                                        \
+    CILK_C_REDUCER_OPAND_TYPE(tn) obj =                                       \
+        CILK_C_INIT_REDUCER(_Typeof(obj.value),                               \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_opand_reduce_,tn),   \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_opand_identity_,tn), \
+                        __cilkrts_hyperobject_noop_destroy, v)
+
+/// @cond internal
+
+/** Declare the op_and reducer functions for a numeric type.
+ *
+ *  This macro expands into external function declarations for functions which
+ *  implement the reducer functionality for the op_and reducer type for a
+ *  specified numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer
+ *              type name, function names, etc.
+ */
+#define CILK_C_REDUCER_OPAND_DECLARATION(t,tn)                             \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPAND_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opand,tn,l,r);         \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opand,tn);
+/** Define the op_and reducer functions for a numeric type.
+ *
+ *  This macro expands into function definitions for functions which implement
+ *  the reducer functionality for the op_and reducer type for a specified
+ *  numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer
+ *              type name, function names, etc.
+ */
+#define CILK_C_REDUCER_OPAND_DEFINITION(t,tn)                              \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPAND_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opand,tn,l,r)          \
+        { *(t*)l &= *(t*)r; }                                              \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opand,tn)            \
+        { *(t*)v = ~((t)0); }
+//@{
+/** @def CILK_C_REDUCER_OPAND_INSTANCE 
+ *  @brief Declare or define implementation functions for a reducer type.
+ *
+ *  In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS`
+ *  will be defined, and this macro will generate reducer implementation
+ *  functions. Everywhere else, `CILK_C_DEFINE_REDUCERS` will be undefined, and
+ *  this macro will expand into external declarations for the functions.
+ */
+#ifdef CILK_C_DEFINE_REDUCERS
+#   define CILK_C_REDUCER_OPAND_INSTANCE(t,tn)  \
+        CILK_C_REDUCER_OPAND_DEFINITION(t,tn)
+#else
+#   define CILK_C_REDUCER_OPAND_INSTANCE(t,tn)  \
+        CILK_C_REDUCER_OPAND_DECLARATION(t,tn)
+#endif
+//@}
+
+/*  Declare or define an instance of the reducer type and its functions for
+ *  each numeric type.
+ */
+CILK_C_REDUCER_OPAND_INSTANCE(char,                 char)
+CILK_C_REDUCER_OPAND_INSTANCE(unsigned char,        uchar)
+CILK_C_REDUCER_OPAND_INSTANCE(signed char,          schar)
+CILK_C_REDUCER_OPAND_INSTANCE(wchar_t,              wchar_t)
+CILK_C_REDUCER_OPAND_INSTANCE(short,                short)
+CILK_C_REDUCER_OPAND_INSTANCE(unsigned short,       ushort)
+CILK_C_REDUCER_OPAND_INSTANCE(int,                  int)
+CILK_C_REDUCER_OPAND_INSTANCE(unsigned int,         uint)
+CILK_C_REDUCER_OPAND_INSTANCE(unsigned int,         unsigned) /* alternate name */
+CILK_C_REDUCER_OPAND_INSTANCE(long,                 long)
+CILK_C_REDUCER_OPAND_INSTANCE(unsigned long,        ulong)
+CILK_C_REDUCER_OPAND_INSTANCE(long long,            longlong)
+CILK_C_REDUCER_OPAND_INSTANCE(unsigned long long,   ulonglong)
+
+//@endcond
+
+__CILKRTS_END_EXTERN_C
+
+//@}
+
+//@}
+
+#endif /*  REDUCER_OPAND_H_INCLUDED */
diff --git a/libcilkrts/include/cilk/reducer_opmul.h b/libcilkrts/include/cilk/reducer_opmul.h
new file mode 100644 (file)
index 0000000..271529d
--- /dev/null
@@ -0,0 +1,442 @@
+/*  reducer_opmul.h                  -*- C++ -*-
+ *
+ *  @copyright
+ *  Copyright (C) 2012-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file reducer_opmul.h
+ *
+ *  @brief Defines classes for doing parallel multiplication reductions.
+ *
+ *  @ingroup ReducersMul
+ *
+ *  @see ReducersMul
+ */
+
+#ifndef REDUCER_OPMUL_H_INCLUDED
+#define REDUCER_OPMUL_H_INCLUDED
+
+#include <cilk/reducer.h>
+
+/** @defgroup ReducersMul Multiplication Reducers
+ *
+ *  Multiplication reducers allow the computation of the product of a set of
+ *  values in parallel.
+ *
+ *  @ingroup Reducers
+ *
+ *  You should be familiar with @ref pagereducers "Cilk reducers", described in
+ *  file `reducers.md`, and particularly with @ref reducers_using, before trying
+ *  to use the information in this file.
+ *
+ *  @section redopmul_usage Usage Example
+ *
+ *      cilk::reducer< cilk::op_mul<double> > r;
+ *      cilk_for (int i = 0; i != N; ++i) {
+ *          *r *= a[i];
+ *      }
+ *      double product;
+ *      r.move_out(product);
+ *
+ *  @section redopmul_monoid The Monoid
+ *
+ *  @subsection redopmul_monoid_values Value Set
+ *
+ *  The value set of a multiplication reducer is the set of values of `Type`,
+ *  which is expected to be a builtin numeric type (or something like it, such
+ *  as `std::complex`).
+ *
+ *  @subsection redopmul_monoid_operator Operator
+ *
+ *  The operator of a multiplication reducer is the multiplication operation,
+ *  defined by the “`*`” binary operator on `Type`.
+ *
+ *  @subsection redopmul_monoid_identity Identity
+ *
+ *  The identity value of the reducer is the numeric value “`1`”. This is
+ *  expected to be the value of the expression `Type(1)`.
+ *
+ *  @section redopmul_operations Operations
+ *
+ *  @subsection redopmul_constructors Constructors
+ *
+ *      reducer()   // identity
+ *      reducer(const Type& value)
+ *      reducer(move_in(Type& variable))
+ *
+ *  @subsection redopmul_get_set Set and Get
+ *
+ *      r.set_value(const Type& value)
+ *      const Type& = r.get_value() const
+ *      r.move_in(Type& variable)
+ *      r.move_out(Type& variable)
+ *
+ *  @subsection redopmul_initial Initial Values
+ *
+ *  If a multiplication reducer is constructed without an explicit initial
+ *  value, then its initial value will be its identity value, as long as `Type`
+ *  satisfies the requirements of @ref redopmul_types.
+ *
+ *  @subsection redopmul_view_ops View Operations
+ *
+ *      *r *= a
+ *      *r = *r * a
+ *      *r = *r * a1 * a2 … * an
+ *
+ *  @section redopmul_floating_point Issues with Floating-Point Types
+ *
+ *  Because of overflow and underflow issues, floating-point multiplication is
+ *  not really associative. For example, `(1e200 * 1e-200) * 1e-200 == 1e-200`,
+ *  but `1e200 * (1e-200 * 1e-200 == 0.
+ *
+ *  In many cases, this won’t matter, but computations which have been
+ *  carefully ordered to control overflow and underflow may not deal well with
+ *  being reassociated. In general, you should be sure to understand the
+ *  floating-point behavior of your program before doing any transformation 
+ *  that will reassociate its computations. 
+ *
+ *  @section redopmul_types Type and Operator Requirements
+ *
+ *  `Type` must be `Copy Constructible`, `Default Constructible`, and 
+ *  `Assignable`.
+ *
+ *  The operator “`*=`” must be defined on `Type`, with `x *= a` having the same
+ *  meaning as `x = x * a`.
+ *
+ *  The expression `Type(1)` must be a valid expression which yields the
+ *  identity value (the value of `Type` whose numeric value is `1`).
+ *
+ *  @section redopmul_in_c Multiplication Reducers in C
+ *
+ *  The @ref CILK_C_REDUCER_OPMUL and @ref CILK_C_REDUCER_OPMUL_TYPE macros can
+ *  be used to do multiplication reductions in C. For example:
+ *
+ *      CILK_C_REDUCER_OPMUL(r, double, 1);
+ *      CILK_C_REGISTER_REDUCER(r);
+ *      cilk_for(int i = 0; i != n; ++i) {
+ *          REDUCER_VIEW(r) *= a[i];
+ *      }
+ *      CILK_C_UNREGISTER_REDUCER(r);
+ *      printf("The product of the elements of a is %f\n", REDUCER_VIEW(r));
+ *
+ *  See @ref reducers_c_predefined.
+ */
+
+#ifdef __cplusplus
+
+namespace cilk {
+
+/** The multiplication reducer view class.
+ *
+ *  This is the view class for reducers created with 
+ *  `cilk::reducer< cilk::op_mul<Type> >`. It holds the accumulator variable 
+ *  for the reduction, and allows only multiplication operations to be 
+ *  performed on it.
+ *
+ *  @note   The reducer “dereference” operation (`reducer::operator *()`) 
+ *          yields a reference to the view. Thus, for example, the view class’s
+ *          `*=` operation would be used in an expression like `*r *= a`, where
+ *          `r` is an op_mul reducer variable.
+ *
+ *  @tparam Type    The type of the contained accumulator variable. This will 
+ *                  be the value type of a monoid_with_view that is 
+ *                  instantiated with this view.
+ *
+ *  @see ReducersMul
+ *  @see op_mul
+ *
+ *  @ingroup ReducersMul
+ */
+template <typename Type>
+class op_mul_view : public scalar_view<Type>
+{
+    typedef scalar_view<Type> base;
+    
+public:
+    /** Class to represent the right-hand side of `*reducer = *reducer * value`.
+     *
+     *  The only assignment operator for the op_mul_view class takes an 
+     *  rhs_proxy as its operand. This results in the syntactic restriction 
+     *  that the only expressions that can be assigned to an op_mul_view are
+     *  ones which generate an rhs_proxy — that is, expressions of the form
+     *  `op_mul_view * value ... * value`.
+     *
+     *  @warning
+     *  The lhs and rhs views in such an assignment must be the same; 
+     *  otherwise, the behavior will be undefined. (I.e., `v1 = v1 * x` is
+     *  legal; `v1 = v2 * x` is illegal.) This condition will be checked with a
+     *  runtime assertion when compiled in debug mode.
+     *
+     *  @see op_mul_view
+     */
+    class rhs_proxy {
+        friend class op_mul_view;
+
+        const op_mul_view* m_view;
+        Type               m_value;
+
+        // Constructor is invoked only from op_mul_view::operator*().
+        //
+        rhs_proxy(const op_mul_view* view, const Type& value) : m_view(view), m_value(value) {}
+
+        rhs_proxy& operator=(const rhs_proxy&); // Disable assignment operator
+        rhs_proxy();                            // Disable default constructor
+
+    public:
+        /** Multiply by an additional rhs value. If `v` is an op_mul_view and 
+         *  `a1` is a value, then the expression `v * a1` invokes the view’s
+         *  `operator*()` to create an rhs_proxy for `(v, a1)`; then 
+         *  `v * a1 * a2` invokes the rhs_proxy’s `operator*()` to create a
+         *  new rhs_proxy for `(v, a1*a2)`. This allows the right-hand side of
+         *  an assignment to be not just `view * value`, but 
+         *  `view * value * value ... * value`. The effect is that
+         *
+         *      v = v * a1 * a2 ... * an;
+         *
+         *  is evaluated as
+         *
+         *      v = v * (a1 * a2 ... * an);
+         */
+        rhs_proxy& operator*(const Type& x) { m_value *= x; return *this; }
+    };
+
+
+    /** Default/identity constructor. This constructor initializes the 
+     *  contained value to `Type(1)`, which is expected to be the identity
+     *  value for multiplication on `Type`.
+     */
+    op_mul_view() : base(Type(1)) {}
+
+    /** Construct with a specified initial value.
+     */
+    explicit op_mul_view(const Type& v) : base(v) {}
+    
+    /** Reduction operation.
+     *
+     *  This function is invoked by the @ref op_mul monoid to combine the views
+     *  of two strands when the right strand merges with the left one. It
+     *  multiplies the value contained in the left-strand view by the value
+     *  contained in the right-strand view, and leaves the value in the
+     *  right-strand view undefined.
+     *
+     *  @param  right   A pointer to the right-strand view. (`this` points to
+     *                  the left-strand view.)
+     *
+     *  @note   Used only by the @ref op_mul monoid to implement the monoid
+     *          reduce operation.
+     */
+    void reduce(op_mul_view* right) { this->m_value *= right->m_value; }
+    
+    /** @name Accumulator variable updates.
+     *
+     *  These functions support the various syntaxes for multiplying the
+     *  accumulator variable contained in the view by some value.
+     */
+    //@{
+
+    /** Multiply the accumulator variable by @a x.
+     */
+    op_mul_view& operator*=(const Type& x) { this->m_value *= x; return *this; }
+
+    /** Create an object representing `*this * x`.
+     *
+     *  @see rhs_proxy
+     */
+    rhs_proxy operator*(const Type& x) const { return rhs_proxy(this, x); }
+
+    /** Assign the result of a `view * value` expression to the view. Note that
+     *  this is the only assignment operator for this class.
+     *
+     *  @see rhs_proxy
+     */
+    op_mul_view& operator=(const rhs_proxy& rhs) {
+        __CILKRTS_ASSERT(this == rhs.m_view);
+        this->m_value *= rhs.m_value;
+        return *this;
+    }
+    
+    //@}
+};
+
+/** Monoid class for multiplication reductions. Instantiate the cilk::reducer
+ *  template class with an op_mul monoid to create a multiplication reducer
+ *  class. For example, to compute the product of a set of `double` values:
+ *
+ *      cilk::reducer< cilk::op_mul<double> > r;
+ *
+ *  @see ReducersMul
+ *  @see op_mul_view
+ *
+ *  @ingroup ReducersMul
+ */
+template <typename Type>
+struct op_mul : public monoid_with_view< op_mul_view<Type> > {};
+
+} // namespace cilk
+
+#endif // __cplusplus
+
+
+/** @ingroup ReducersAdd
+ */
+//@{
+
+/** @name C language reducer macros
+ *
+ *  These macros are used to declare and work with numeric op_mul reducers in
+ *  C code.
+ *
+ *  @see @ref page_reducers_in_c
+ */
+ //@{
+__CILKRTS_BEGIN_EXTERN_C
+
+/** Opmul reducer type name.
+ *
+ *  This macro expands into the identifier which is the name of the op_mul
+ *  reducer type for a specified numeric type.
+ *
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying
+ *              the type of the reducer.
+ *
+ *  @see @ref reducers_c_predefined
+ *  @see ReducersMul
+ */
+#define CILK_C_REDUCER_OPMUL_TYPE(tn)                                         \
+    __CILKRTS_MKIDENT(cilk_c_reducer_opmul_,tn)
+
+/** Declare an op_mul reducer object.
+ *
+ *  This macro expands into a declaration of an op_mul reducer object for a
+ *  specified numeric type. For example:
+ *
+ *      CILK_C_REDUCER_OPMUL(my_reducer, double, 1.0);
+ *
+ *  @param  obj The variable name to be used for the declared reducer object.
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying
+ *              the type of the reducer.
+ *  @param  v   The initial value for the reducer. (A value which can be
+ *              assigned to the numeric type represented by @a tn.)
+ *
+ *  @see @ref reducers_c_predefined
+ *  @see ReducersMul
+ */
+#define CILK_C_REDUCER_OPMUL(obj,tn,v)                                        \
+    CILK_C_REDUCER_OPMUL_TYPE(tn) obj =                                       \
+        CILK_C_INIT_REDUCER(_Typeof(obj.value),                               \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_opmul_reduce_,tn),   \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_opmul_identity_,tn), \
+                        __cilkrts_hyperobject_noop_destroy, v)
+
+/// @cond internal
+
+/** Declare the op_mul reducer functions for a numeric type.
+ *
+ *  This macro expands into external function declarations for functions which 
+ *  implement the reducer functionality for the op_mul reducer type for a
+ *  specified numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer
+ *              type name, function names, etc.
+ */
+#define CILK_C_REDUCER_OPMUL_DECLARATION(t,tn)                             \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPMUL_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opmul,tn,l,r);         \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opmul,tn);
+/** Define the op_mul reducer functions for a numeric type.
+ *
+ *  This macro expands into function definitions for functions which implement
+ *  the reducer functionality for the op_mul reducer type for a specified
+ *  numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer
+ *              type name, function names, etc.
+ */
+#define CILK_C_REDUCER_OPMUL_DEFINITION(t,tn)                              \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPMUL_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opmul,tn,l,r)          \
+        { *(t*)l *= *(t*)r; }                                              \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opmul,tn)            \
+        { *(t*)v = 1; }
+//@{
+/** @def CILK_C_REDUCER_OPMUL_INSTANCE 
+ *  @brief Declare or define implementation functions for a reducer type.
+ *
+ *  In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS`
+ *  will be defined, and this macro will generate reducer implementation
+ *  functions. Everywhere else, `CILK_C_DEFINE_REDUCERS` will be undefined, and
+ *  this macro will expand into external declarations for the functions.
+ */
+#ifdef CILK_C_DEFINE_REDUCERS
+#   define CILK_C_REDUCER_OPMUL_INSTANCE(t,tn)  \
+        CILK_C_REDUCER_OPMUL_DEFINITION(t,tn)
+#else
+#   define CILK_C_REDUCER_OPMUL_INSTANCE(t,tn)  \
+        CILK_C_REDUCER_OPMUL_DECLARATION(t,tn)
+#endif
+//@}
+
+/*  Declare or define an instance of the reducer type and its functions for each 
+ *  numeric type.
+ */
+CILK_C_REDUCER_OPMUL_INSTANCE(char,                 char)
+CILK_C_REDUCER_OPMUL_INSTANCE(unsigned char,        uchar)
+CILK_C_REDUCER_OPMUL_INSTANCE(signed char,          schar)
+CILK_C_REDUCER_OPMUL_INSTANCE(wchar_t,              wchar_t)
+CILK_C_REDUCER_OPMUL_INSTANCE(short,                short)
+CILK_C_REDUCER_OPMUL_INSTANCE(unsigned short,       ushort)
+CILK_C_REDUCER_OPMUL_INSTANCE(int,                  int)
+CILK_C_REDUCER_OPMUL_INSTANCE(unsigned int,         uint)
+CILK_C_REDUCER_OPMUL_INSTANCE(unsigned int,         unsigned) /* alternate name */
+CILK_C_REDUCER_OPMUL_INSTANCE(long,                 long)
+CILK_C_REDUCER_OPMUL_INSTANCE(unsigned long,        ulong)
+CILK_C_REDUCER_OPMUL_INSTANCE(long long,            longlong)
+CILK_C_REDUCER_OPMUL_INSTANCE(unsigned long long,   ulonglong)
+CILK_C_REDUCER_OPMUL_INSTANCE(float,                float)
+CILK_C_REDUCER_OPMUL_INSTANCE(double,               double)
+CILK_C_REDUCER_OPMUL_INSTANCE(long double,          longdouble)
+
+//@endcond
+
+__CILKRTS_END_EXTERN_C
+
+//@}
+
+//@}
+
+#endif /*  REDUCER_OPMUL_H_INCLUDED */
diff --git a/libcilkrts/include/cilk/reducer_opor.h b/libcilkrts/include/cilk/reducer_opor.h
new file mode 100644 (file)
index 0000000..5c8e7bd
--- /dev/null
@@ -0,0 +1,598 @@
+/*  reducer_opor.h                  -*- C++ -*-
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file reducer_opor.h
+ *
+ *  @brief Defines classes for doing parallel bitwise or reductions.
+ *
+ *  @ingroup ReducersOr
+ *
+ *  @see ReducersOr
+ */
+
+#ifndef REDUCER_OPOR_H_INCLUDED
+#define REDUCER_OPOR_H_INCLUDED
+
+#include <cilk/reducer.h>
+
+/** @defgroup ReducersOr Bitwise Or Reducers
+ *
+ *  Bitwise and reducers allow the computation of the bitwise and of a set of
+ *  values in parallel.
+ *
+ *  @ingroup Reducers
+ *
+ *  You should be familiar with @ref pagereducers "Cilk reducers", described in
+ *  file `reducers.md`, and particularly with @ref reducers_using, before trying
+ *  to use the information in this file.
+ *
+ *  @section redopor_usage Usage Example
+ *
+ *      cilk::reducer< cilk::op_or<unsigned> > r;
+ *      cilk_for (int i = 0; i != N; ++i) {
+ *          *r |= a[i];
+ *      }
+ *      unsigned result;
+ *      r.move_out(result);
+ *
+ *  @section redopor_monoid The Monoid
+ *
+ *  @subsection redopor_monoid_values Value Set
+ *
+ *  The value set of a bitwise or reducer is the set of values of `Type`, which
+ *  is expected to be a builtin integer type which has a representation as a
+ *  sequence of bits (or something like it, such as `bool` or `std::bitset`).
+ *
+ *  @subsection redopor_monoid_operator Operator
+ *
+ *  The operator of a bitwise or reducer is the bitwise or operator, defined by
+ *  the “`|`” binary operator on `Type`.
+ *
+ *  @subsection redopor_monoid_identity Identity
+ *
+ *  The identity value of the reducer is the value whose representation 
+ *  contains all 0-bits. This is expected to be the value of the default
+ *  constructor `Type()`.
+ *
+ *  @section redopor_operations Operations
+ *
+ *  @subsection redopor_constructors Constructors
+ *
+ *      reducer()   // identity
+ *      reducer(const Type& value)
+ *      reducer(move_in(Type& variable))
+ *
+ *  @subsection redopor_get_set Set and Get
+ *
+ *      r.set_value(const Type& value)
+ *      const Type& = r.get_value() const
+ *      r.move_in(Type& variable)
+ *      r.move_out(Type& variable)
+ *
+ *  @subsection redopor_initial Initial Values
+ *
+ *  If a bitwise or reducer is constructed without an explicit initial value, 
+ *  then its initial value will be its identity value, as long as `Type` 
+ *  satisfies the requirements of @ref redopor_types.
+ *
+ *  @subsection redopor_view_ops View Operations
+ *
+ *      *r |= a
+ *      *r = *r | a
+ *      *r = *r | a1 | a2 … | an
+ *
+ *  @section redopor_types Type and Operator Requirements
+ *
+ *  `Type` must be `Copy Constructible`, `Default Constructible`, and
+ *  `Assignable`.
+ *
+ *  The operator “`|=`” must be defined on `Type`, with `x |= a` having the 
+ *  same meaning as `x = x | a`.
+ *
+ *  The expression `Type()` must be a valid expression which yields the
+ *  identity value (the value of `Type` whose representation consists of all
+ *  0-bits).
+ *
+ *  @section redopor_in_c Bitwise Or Reducers in C
+ *
+ *  The @ref CILK_C_REDUCER_OPOR and @ref CILK_C_REDUCER_OPOR_TYPE macros can
+ *  be used to do bitwise or reductions in C. For example:
+ *
+ *      CILK_C_REDUCER_OPOR(r, uint, 0);
+ *      CILK_C_REGISTER_REDUCER(r);
+ *      cilk_for(int i = 0; i != n; ++i) {
+ *          REDUCER_VIEW(r) |= a[i];
+ *      }
+ *      CILK_C_UNREGISTER_REDUCER(r);
+ *      printf("The bitwise OR of the elements of a is %x\n", REDUCER_VIEW(r));
+ *
+ *  See @ref reducers_c_predefined.
+ */
+
+#ifdef __cplusplus
+
+namespace cilk {
+
+/** The bitwise or reducer view class.
+ *
+ *  This is the view class for reducers created with 
+ *  `cilk::reducer< cilk::op_or<Type> >`. It holds the accumulator variable for
+ *  the reduction, and allows only `or` operations to be performed on it.
+ *
+ *  @note   The reducer “dereference” operation (`reducer::operator *()`) 
+ *          yields a reference to the view. Thus, for example, the view class’s
+ *          `|=` operation would be used in an expression like `*r |= a`, where
+ *          `r` is an opmod reducer variable.
+ *
+ *  @tparam Type    The type of the contained accumulator variable. This will
+ *                  be the value type of a monoid_with_view that is
+ *                  instantiated with this view.
+ *
+ *  @see ReducersOr
+ *  @see op_or
+ *
+ *  @ingroup ReducersOr
+ */
+template <typename Type>
+class op_or_view : public scalar_view<Type>
+{
+    typedef scalar_view<Type> base;
+    
+public:
+    /** Class to represent the right-hand side of `*reducer = *reducer | value`.
+     *
+     *  The only assignment operator for the op_or_view class takes an 
+     *  rhs_proxy as its operand. This results in the syntactic restriction
+     *  that the only expressions that can be assigned to an op_or_view are
+     *  ones which generate an rhs_proxy — that is, expressions of the form
+     *  `op_or_view | value ... | value`.
+     *
+     *  @warning
+     *  The lhs and rhs views in such an assignment must be the same; 
+     *  otherwise, the behavior will be undefined. (I.e., `v1 = v1 | x` is
+     *  legal; `v1 = v2 | x` is illegal.) This condition will be checked with
+     *  a runtime assertion when compiled in debug mode.
+     *
+     *  @see op_or_view
+     */
+    class rhs_proxy {
+        friend class op_or_view;
+
+        const op_or_view* m_view;
+        Type              m_value;
+
+        // Constructor is invoked only from op_or_view::operator|().
+        //
+        rhs_proxy(const op_or_view* view, const Type& value) : m_view(view), m_value(value) {}
+
+        rhs_proxy& operator=(const rhs_proxy&); // Disable assignment operator
+        rhs_proxy();                            // Disable default constructor
+
+    public:
+        /** Bitwise or with an additional rhs value. If `v` is an op_or_view
+         *  and `a1` is a value, then the expression `v | a1` invokes the 
+         *  view’s `operator|()` to create an rhs_proxy for `(v, a1)`; then 
+         *  `v | a1 | a2` invokes the rhs_proxy’s `operator|()` to create a new
+         *  rhs_proxy for `(v, a1|a2)`. This allows the right-hand side of an
+         *  assignment to be not just `view | value`, but 
+         (  `view | value | value ... | value`. The effect is that
+         *
+         *      v = v | a1 | a2 ... | an;
+         *
+         *  is evaluated as
+         *
+         *      v = v | (a1 | a2 ... | an);
+         */
+        rhs_proxy& operator|(const Type& x) { m_value |= x; return *this; }
+    };
+
+
+    /** Default/identity constructor. This constructor initializes the
+     *  contained value to `Type()`.
+     */
+    op_or_view() : base() {}
+
+    /** Construct with a specified initial value.
+     */
+    explicit op_or_view(const Type& v) : base(v) {}
+    
+    /** Reduction operation.
+     *
+     *  This function is invoked by the @ref op_or monoid to combine the views
+     *  of two strands when the right strand merges with the left one. It
+     *  “ors” the value contained in the left-strand view by the value
+     *  contained in the right-strand view, and leaves the value in the
+     *  right-strand view undefined.
+     *
+     *  @param  right   A pointer to the right-strand view. (`this` points to
+     *                  the left-strand view.)
+     *
+     *  @note   Used only by the @ref op_or monoid to implement the monoid
+     *          reduce operation.
+     */
+    void reduce(op_or_view* right) { this->m_value |= right->m_value; }
+    
+    /** @name Accumulator variable updates.
+     *
+     *  These functions support the various syntaxes for “oring” the
+     *  accumulator variable contained in the view with some value.
+     */
+    //@{
+
+    /** Or the accumulator variable with @a x.
+     */
+    op_or_view& operator|=(const Type& x) { this->m_value |= x; return *this; }
+
+    /** Create an object representing `*this | x`.
+     *
+     *  @see rhs_proxy
+     */
+    rhs_proxy operator|(const Type& x) const { return rhs_proxy(this, x); }
+
+    /** Assign the result of a `view | value` expression to the view. Note that
+     *  this is the only assignment operator for this class.
+     *
+     *  @see rhs_proxy
+     */
+    op_or_view& operator=(const rhs_proxy& rhs) {
+        __CILKRTS_ASSERT(this == rhs.m_view);
+        this->m_value |= rhs.m_value;
+        return *this;
+    }
+    
+    //@}
+};
+
+/** Monoid class for bitwise or reductions. Instantiate the cilk::reducer 
+ *  template class with an op_or monoid to create a bitwise or reducer
+ *  class. For example, to compute the bitwise or of a set of `unsigned long`
+ *  values:
+ *
+ *      cilk::reducer< cilk::op_or<unsigned long> > r;
+ *
+ *  @tparam Type    The reducer value type.
+ *  @tparam Align   If `false` (the default), reducers instantiated on this
+ *                  monoid will be naturally aligned (the Cilk library 1.0
+ *                  behavior). If `true`, reducers instantiated on this monoid
+ *                  will be cache-aligned for binary compatibility with 
+ *                  reducers in Cilk library version 0.9.
+ *
+ *  @see ReducersOr
+ *  @see op_or_view
+ *
+ *  @ingroup ReducersOr
+ */
+template <typename Type, bool Align = false>
+struct op_or : public monoid_with_view<op_or_view<Type>, Align> {};
+
+/** Deprecated bitwise or reducer class.
+ *
+ *  reducer_opor is the same as @ref reducer<@ref op_or>, except that
+ *  reducer_opor is a proxy for the contained view, so that accumulator
+ *  variable update operations can be applied directly to the reducer. For
+ *  example, a value is ored with  a `reducer<%op_or>` with `*r |= a`, but a
+ *  value can be ored with a `%reducer_opor` with `r |= a`.
+ *
+ *  @deprecated Users are strongly encouraged to use `reducer<monoid>`
+ *              reducers rather than the old wrappers like reducer_opor. 
+ *              The `reducer<monoid>` reducers show the reducer/monoid/view
+ *              architecture more clearly, are more consistent in their
+ *              implementation, and present a simpler model for new
+ *              user-implemented reducers.
+ *
+ *  @note   Implicit conversions are provided between `%reducer_opor` 
+ *          and `reducer<%op_or>`. This allows incremental code
+ *          conversion: old code that used `%reducer_opor` can pass a
+ *          `%reducer_opor` to a converted function that now expects a
+ *          pointer or reference to a `reducer<%op_or>`, and vice
+ *          versa.
+ *
+ *  @tparam Type    The value type of the reducer.
+ *
+ *  @see op_or
+ *  @see reducer
+ *  @see ReducersOr
+ *
+ *  @ingroup ReducersOr
+ */
+template <typename Type>
+class reducer_opor : public reducer< op_or<Type, true> >
+{
+    typedef reducer< op_or<Type, true> > base;
+    using base::view;
+
+  public:
+    /// The view type for the reducer.
+    typedef typename base::view_type        view_type;
+    
+    /// The view’s rhs proxy type.
+    typedef typename view_type::rhs_proxy   rhs_proxy;
+    
+    /// The view type for the reducer.
+    typedef view_type                       View;
+
+    /// The monoid type for the reducer.
+    typedef typename base::monoid_type      Monoid;
+    
+    /** @name Constructors
+     */
+    //@{
+    
+    /** Default (identity) constructor.
+     *
+     * Constructs the wrapper with the default initial value of `Type()`.
+     */
+    reducer_opor() {}
+
+    /** Value constructor.
+     *
+     *  Constructs the wrapper with a specified initial value.
+     */
+    explicit reducer_opor(const Type& initial_value) : base(initial_value) {}
+    
+    //@}
+
+    /** @name Forwarded functions
+     *  @details Functions that update the contained accumulator variable are
+     *  simply forwarded to the contained @ref op_and_view. */
+    //@{
+
+    /// @copydoc op_or_view::operator|=(const Type&)
+    reducer_opor& operator|=(const Type& x)
+    {
+        view() |= x; return *this; 
+    }
+    
+    // The legacy definition of reducer_opor::operator|() has different
+    // behavior and a different return type than this definition. The legacy
+    // version is defined as a member function, so this new version is defined
+    // as a free function to give it a different signature, so that they won’t 
+    // end up sharing a single object file entry.
+
+    /// @copydoc op_or_view::operator|(const Type&) const
+    friend rhs_proxy operator|(const reducer_opor& r, const Type& x)
+    { 
+        return r.view() | x; 
+    }
+
+    /// @copydoc op_and_view::operator=(const rhs_proxy&)
+    reducer_opor& operator=(const rhs_proxy& temp)
+    {
+        view() = temp; return *this; 
+    }
+    //@}
+
+    /** @name Dereference
+     *  @details Dereferencing a wrapper is a no-op. It simply returns the
+     *  wrapper. Combined with the rule that the wrapper forwards view
+     *  operations to its contained view, this means that view operations can
+     *  be written the same way on reducers and wrappers, which is convenient
+     *  for incrementally converting old code using wrappers to use reducers
+     *  instead. That is:
+     *
+     *      reducer< op_and<int> > r;
+     *      *r &= a;    // *r returns the view
+     *                  // operator &= is a view member function
+     *
+     *      reducer_opand<int> w;
+     *      *w &= a;    // *w returns the wrapper
+     *                  // operator &= is a wrapper member function that
+     *                  // calls the corresponding view function
+     */
+    //@{
+    reducer_opor&       operator*()       { return *this; }
+    reducer_opor const& operator*() const { return *this; }
+
+    reducer_opor*       operator->()       { return this; }
+    reducer_opor const* operator->() const { return this; }
+    //@}
+    
+    /** @name Upcast
+     *  @details In Cilk library 0.9, reducers were always cache-aligned. In
+     *  library  1.0, reducer cache alignment is optional. By default, reducers
+     *  are unaligned (i.e., just naturally aligned), but legacy wrappers
+     *  inherit from cache-aligned reducers for binary compatibility.
+     *
+     *  This means that a wrapper will automatically be upcast to its aligned
+     *  reducer base class. The following conversion operators provide
+     *  pseudo-upcasts to the corresponding unaligned reducer class.
+     */
+    //@{
+    operator reducer< op_or<Type, false> >& ()
+    {
+        return *reinterpret_cast< reducer< op_or<Type, false> >* >(this);
+    }
+    operator const reducer< op_or<Type, false> >& () const
+    {
+        return *reinterpret_cast< const reducer< op_or<Type, false> >* >(this);
+    }
+    //@}
+    
+};
+
+/// @cond internal
+/** Metafunction specialization for reducer conversion.
+ *
+ *  This specialization of the @ref legacy_reducer_downcast template class 
+ *  defined in reducer.h causes the `reducer< op_or<Type> >` class to have an 
+ *  `operator reducer_opor<Type>& ()` conversion operator that statically
+ *  downcasts the `reducer<op_or>` to the corresponding `reducer_opor` type.
+ *  (The reverse conversion, from `reducer_opor` to `reducer<op_or>`, is just
+ *  an upcast, which is provided for free by the language.)
+ *
+ *  @ingroup ReducersOr
+ */
+template <typename Type, bool Align>
+struct legacy_reducer_downcast<reducer<op_or<Type, Align> > >
+{
+    typedef reducer_opor<Type> type;
+};
+/// @endcond
+
+} // namespace cilk
+
+#endif /* __cplusplus */
+
+
+/** @ingroup ReducersOr
+ */
+//@{
+
+/** @name C language reducer macros
+ *
+ *  These macros are used to declare and work with op_or reducers in C code.
+ *
+ *  @see @ref page_reducers_in_c
+ */
+ //@{
+__CILKRTS_BEGIN_EXTERN_C
+
+/** Opor reducer type name.
+ *
+ *  This macro expands into the identifier which is the name of the op_or
+ *  reducer type for a specified numeric type.
+ *
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying
+ *              the type of the reducer.
+ *
+ *  @see @ref reducers_c_predefined
+ *  @see ReducersOr
+ */
+#define CILK_C_REDUCER_OPOR_TYPE(tn)                                         \
+    __CILKRTS_MKIDENT(cilk_c_reducer_opor_,tn)
+
+/** Declare an op_or reducer object.
+ *
+ *  This macro expands into a declaration of an op_or reducer object for a
+ *  specified numeric type. For example:
+ *
+ *      CILK_C_REDUCER_OPOR(my_reducer, ulong, 0);
+ *
+ *  @param  obj The variable name to be used for the declared reducer object.
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying
+ *              the type of the reducer.
+ *  @param  v   The initial value for the reducer. (A value which can be
+ *              assigned to the numeric type represented by @a tn.)
+ *
+ *  @see @ref reducers_c_predefined
+ *  @see ReducersOr
+ */
+#define CILK_C_REDUCER_OPOR(obj,tn,v)                                        \
+    CILK_C_REDUCER_OPOR_TYPE(tn) obj =                                       \
+        CILK_C_INIT_REDUCER(_Typeof(obj.value),                               \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_opor_reduce_,tn),   \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_opor_identity_,tn), \
+                        __cilkrts_hyperobject_noop_destroy, v)
+
+/// @cond internal
+
+/** Declare the op_or reducer functions for a numeric type.
+ *
+ *  This macro expands into external function declarations for functions which
+ *  implement the reducer functionality for the op_or reducer type for a
+ *  specified numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer
+ *              type name, function names, etc.
+ */
+#define CILK_C_REDUCER_OPOR_DECLARATION(t,tn)                             \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPOR_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opor,tn,l,r);         \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opor,tn);
+/** Define the op_or reducer functions for a numeric type.
+ *
+ *  This macro expands into function definitions for functions which implement
+ *  the reducer functionality for the op_or reducer type for a specified 
+ *  numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer
+ *              type name, function names, etc.
+ */
+#define CILK_C_REDUCER_OPOR_DEFINITION(t,tn)                              \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPOR_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opor,tn,l,r)          \
+        { *(t*)l |= *(t*)r; }                                              \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opor,tn)            \
+        { *(t*)v = 0; }
+//@{
+/** @def CILK_C_REDUCER_OPOR_INSTANCE 
+ *  @brief Declare or define implementation functions for a reducer type.
+ *
+ *  In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS`
+ *  will be defined, and this macro will generate reducer implementation
+ *  functions. Everywhere else, `CILK_C_DEFINE_REDUCERS` will be undefined, and
+ *  this macro will expand into external declarations for the functions.
+ */
+#ifdef CILK_C_DEFINE_REDUCERS
+#   define CILK_C_REDUCER_OPOR_INSTANCE(t,tn)  \
+        CILK_C_REDUCER_OPOR_DEFINITION(t,tn)
+#else
+#   define CILK_C_REDUCER_OPOR_INSTANCE(t,tn)  \
+        CILK_C_REDUCER_OPOR_DECLARATION(t,tn)
+#endif
+//@}
+
+/*  Declare or define an instance of the reducer type and its functions for each 
+ *  numeric type.
+ */
+CILK_C_REDUCER_OPOR_INSTANCE(char,                 char)
+CILK_C_REDUCER_OPOR_INSTANCE(unsigned char,        uchar)
+CILK_C_REDUCER_OPOR_INSTANCE(signed char,          schar)
+CILK_C_REDUCER_OPOR_INSTANCE(wchar_t,              wchar_t)
+CILK_C_REDUCER_OPOR_INSTANCE(short,                short)
+CILK_C_REDUCER_OPOR_INSTANCE(unsigned short,       ushort)
+CILK_C_REDUCER_OPOR_INSTANCE(int,                  int)
+CILK_C_REDUCER_OPOR_INSTANCE(unsigned int,         uint)
+CILK_C_REDUCER_OPOR_INSTANCE(unsigned int,         unsigned) /* alternate name */
+CILK_C_REDUCER_OPOR_INSTANCE(long,                 long)
+CILK_C_REDUCER_OPOR_INSTANCE(unsigned long,        ulong)
+CILK_C_REDUCER_OPOR_INSTANCE(long long,            longlong)
+CILK_C_REDUCER_OPOR_INSTANCE(unsigned long long,   ulonglong)
+
+//@endcond
+
+__CILKRTS_END_EXTERN_C
+
+//@}
+
+//@}
+
+#endif /*  REDUCER_OPOR_H_INCLUDED */
diff --git a/libcilkrts/include/cilk/reducer_opxor.h b/libcilkrts/include/cilk/reducer_opxor.h
new file mode 100644 (file)
index 0000000..fed4994
--- /dev/null
@@ -0,0 +1,598 @@
+/*  reducer_opxor.h                  -*- C++ -*-
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file reducer_opxor.h
+ *
+ *  @brief Defines classes for doing parallel bitwise or reductions.
+ *
+ *  @ingroup ReducersXor
+ *
+ *  @see ReducersXor
+ */
+
+#ifndef REDUCER_OPXOR_H_INCLUDED
+#define REDUCER_OPXOR_H_INCLUDED
+
+#include <cilk/reducer.h>
+
+/** @defgroup ReducersXor Bitwise Xor Reducers
+ *
+ *  Bitwise and reducers allow the computation of the bitwise and of a set of
+ *  values in parallel.
+ *
+ *  @ingroup Reducers
+ *
+ *  You should be familiar with @ref pagereducers "Cilk reducers", described in
+ *  file `reducers.md`, and particularly with @ref reducers_using, before trying
+ *  to use the information in this file.
+ *
+ *  @section redopxor_usage Usage Example
+ *
+ *      cilk::reducer< cilk::op_xor<unsigned> > r;
+ *      cilk_for (int i = 0; i != N; ++i) {
+ *          *r ^= a[i];
+ *      }
+ *      unsigned result;
+ *      r.move_out(result);
+ *
+ *  @section redopxor_monoid The Monoid
+ *
+ *  @subsection redopxor_monoid_values Value Set
+ *
+ *  The value set of a bitwise xor reducer is the set of values of `Type`, which
+ *  is expected to be a builtin integer type which has a representation as a
+ *  sequence of bits (or something like it, such as `bool` or `std::bitset`).
+ *
+ *  @subsection redopxor_monoid_operator Operator
+ *
+ *  The operator of a bitwise xor reducer is the bitwise xor operator, defined
+ *  by the “`^`” binary operator on `Type`.
+ *
+ *  @subsection redopxor_monoid_identity Identity
+ *
+ *  The identity value of the reducer is the value whose representation 
+ *  contains all 0-bits. This is expected to be the value of the default
+ *  constructor `Type()`.
+ *
+ *  @section redopxor_operations Operations
+ *
+ *  @subsection redopxor_constructors Constructors
+ *
+ *      reducer()   // identity
+ *      reducer(const Type& value)
+ *      reducer(move_in(Type& variable))
+ *
+ *  @subsection redopxor_get_set Set and Get
+ *
+ *      r.set_value(const Type& value)
+ *      const Type& = r.get_value() const
+ *      r.move_in(Type& variable)
+ *      r.move_out(Type& variable)
+ *
+ *  @subsection redopxor_initial Initial Values
+ *
+ *  If a bitwise xor reducer is constructed without an explicit initial value, 
+ *  then its initial value will be its identity value, as long as `Type` 
+ *  satisfies the requirements of @ref redopxor_types.
+ *
+ *  @subsection redopxor_view_ops View Operations
+ *
+ *      *r ^= a
+ *      *r = *r ^ a
+ *      *r = *r ^ a1 ^ a2 … ^ an
+ *
+ *  @section redopxor_types Type and Operator Requirements
+ *
+ *  `Type` must be `Copy Constructible`, `Default Constructible`, and
+ *  `Assignable`.
+ *
+ *  The operator “`^=`” must be defined on `Type`, with `x ^= a` having the 
+ *  same meaning as `x = x ^ a`.
+ *
+ *  The expression `Type()` must be a valid expression which yields the
+ *  identity value (the value of `Type` whose representation consists of all
+ *  0-bits).
+ *
+ *  @section redopxor_in_c Bitwise Xor Reducers in C
+ *
+ *  The @ref CILK_C_REDUCER_OPXOR and @ref CILK_C_REDUCER_OPXOR_TYPE macros can
+ *  be used to do bitwise xor reductions in C. For example:
+ *
+ *      CILK_C_REDUCER_OPXOR(r, uint, 0);
+ *      CILK_C_REGISTER_REDUCER(r);
+ *      cilk_for(int i = 0; i != n; ++i) {
+ *          REDUCER_VIEW(r) ^= a[i];
+ *      }
+ *      CILK_C_UNREGISTER_REDUCER(r);
+ *      printf("The bitwise XOR of the elements of a is %x\n", REDUCER_VIEW(r));
+ *
+ *  See @ref reducers_c_predefined.
+ */
+
+#ifdef __cplusplus
+
+namespace cilk {
+
+/** The bitwise xor reducer view class.
+ *
+ *  This is the view class for reducers created with 
+ *  `cilk::reducer< cilk::op_xor<Type> >`. It holds the accumulator variable 
+ *  for the reduction, and allows only `xor` operations to be performed on it.
+ *
+ *  @note   The reducer “dereference” operation (`reducer::operator *()`) 
+ *          yields a reference to the view. Thus, for example, the view class’s
+ *          `^=` operation would be used in an expression like `*r ^= a`, where
+ *          `r` is an opmod reducer variable.
+ *
+ *  @tparam Type    The type of the contained accumulator variable. This will
+ *                  be the value type of a monoid_with_view that is
+ *                  instantiated with this view.
+ *
+ *  @see ReducersXor
+ *  @see op_xor
+ *
+ *  @ingroup ReducersXor
+ */
+template <typename Type>
+class op_xor_view : public scalar_view<Type>
+{
+    typedef scalar_view<Type> base;
+    
+public:
+    /** Class to represent the right-hand side of `*reducer = *reducer ^ value`.
+     *
+     *  The only assignment operator for the op_xor_view class takes an 
+     *  rhs_proxy as its operand. This results in the syntactic restriction
+     *  that the only expressions that can be assigned to an op_xor_view are
+     *  ones which generate an rhs_proxy — that is, expressions of the form
+     *  `op_xor_view ^ value ... ^ value`.
+     *
+     *  @warning
+     *  The lhs and rhs views in such an assignment must be the same; 
+     *  otherwise, the behavior will be undefined. (I.e., `v1 = v1 ^ x` is
+     *  legal; `v1 = v2 ^ x` is illegal.) This condition will be checked with
+     *  a runtime assertion when compiled in debug mode.
+     *
+     *  @see op_xor_view
+     */
+    class rhs_proxy {
+        friend class op_xor_view;
+
+        const op_xor_view* m_view;
+        Type              m_value;
+
+        // Constructor is invoked only from op_xor_view::operator^().
+        //
+        rhs_proxy(const op_xor_view* view, const Type& value) : m_view(view), m_value(value) {}
+
+        rhs_proxy& operator=(const rhs_proxy&); // Disable assignment operator
+        rhs_proxy();                            // Disable default constructor
+
+    public:
+        /** Bitwise xor with an additional rhs value. If `v` is an op_xor_view
+         *  and `a1` is a value, then the expression `v ^ a1` invokes the 
+         *  view’s `operator^()` to create an rhs_proxy for `(v, a1)`; then 
+         *  `v ^ a1 ^ a2` invokes the rhs_proxy’s `operator^()` to create a new
+         *  rhs_proxy for `(v, a1^a2)`. This allows the right-hand side of an
+         *  assignment to be not just `view ^ value`, but 
+         (  `view ^ value ^ value ... ^ value`. The effect is that
+         *
+         *      v = v ^ a1 ^ a2 ... ^ an;
+         *
+         *  is evaluated as
+         *
+         *      v = v ^ (a1 ^ a2 ... ^ an);
+         */
+        rhs_proxy& operator^(const Type& x) { m_value ^= x; return *this; }
+    };
+
+
+    /** Default/identity constructor. This constructor initializes the
+     *  contained value to `Type()`.
+     */
+    op_xor_view() : base() {}
+
+    /** Construct with a specified initial value.
+     */
+    explicit op_xor_view(const Type& v) : base(v) {}
+    
+    /** Reduction operation.
+     *
+     *  This function is invoked by the @ref op_xor monoid to combine the views
+     *  of two strands when the right strand merges with the left one. It
+     *  “xors” the value contained in the left-strand view by the value
+     *  contained in the right-strand view, and leaves the value in the
+     *  right-strand view undefined.
+     *
+     *  @param  right   A pointer to the right-strand view. (`this` points to
+     *                  the left-strand view.)
+     *
+     *  @note   Used only by the @ref op_xor monoid to implement the monoid
+     *          reduce operation.
+     */
+    void reduce(op_xor_view* right) { this->m_value ^= right->m_value; }
+    
+    /** @name Accumulator variable updates.
+     *
+     *  These functions support the various syntaxes for “xoring” the
+     *  accumulator variable contained in the view with some value.
+     */
+    //@{
+
+    /** Xor the accumulator variable with @a x.
+     */
+    op_xor_view& operator^=(const Type& x) { this->m_value ^= x; return *this; }
+
+    /** Create an object representing `*this ^ x`.
+     *
+     *  @see rhs_proxy
+     */
+    rhs_proxy operator^(const Type& x) const { return rhs_proxy(this, x); }
+
+    /** Assign the result of a `view ^ value` expression to the view. Note that
+     *  this is the only assignment operator for this class.
+     *
+     *  @see rhs_proxy
+     */
+    op_xor_view& operator=(const rhs_proxy& rhs) {
+        __CILKRTS_ASSERT(this == rhs.m_view);
+        this->m_value ^= rhs.m_value;
+        return *this;
+    }
+    
+    //@}
+};
+
+/** Monoid class for bitwise xor reductions. Instantiate the cilk::reducer 
+ *  template class with an op_xor monoid to create a bitwise xor reducer
+ *  class. For example, to compute the bitwise xor of a set of `unsigned long`
+ *  values:
+ *
+ *      cilk::reducer< cilk::op_xor<unsigned long> > r;
+ *
+ *  @tparam Type    The reducer value type.
+ *  @tparam Align   If `false` (the default), reducers instantiated on this
+ *                  monoid will be naturally aligned (the Cilk library 1.0
+ *                  behavior). If `true`, reducers instantiated on this monoid
+ *                  will be cache-aligned for binary compatibility with 
+ *                  reducers in Cilk library version 0.9.
+ *
+ *  @see ReducersXor
+ *  @see op_xor_view
+ *
+ *  @ingroup ReducersXor
+ */
+template <typename Type, bool Align = false>
+struct op_xor : public monoid_with_view<op_xor_view<Type>, Align> {};
+
+/** Deprecated bitwise xor reducer class.
+ *
+ *  reducer_opxor is the same as @ref reducer<@ref op_xor>, except that
+ *  reducer_opxor is a proxy for the contained view, so that accumulator
+ *  variable update operations can be applied directly to the reducer. For
+ *  example, a value is xored with  a `reducer<%op_xor>` with `*r ^= a`, but a
+ *  value can be xored with a `%reducer_opxor` with `r ^= a`.
+ *
+ *  @deprecated Users are strongly encouraged to use `reducer<monoid>`
+ *              reducers rather than the old wrappers like reducer_opand. 
+ *              The `reducer<monoid>` reducers show the reducer/monoid/view
+ *              architecture more clearly, are more consistent in their
+ *              implementation, and present a simpler model for new
+ *              user-implemented reducers.
+ *
+ *  @note   Implicit conversions are provided between `%reducer_opxor` 
+ *          and `reducer<%op_xor>`. This allows incremental code
+ *          conversion: old code that used `%reducer_opxor` can pass a
+ *          `%reducer_opxor` to a converted function that now expects a
+ *          pointer or reference to a `reducer<%op_xor>`, and vice
+ *          versa.
+ *
+ *  @tparam Type    The value type of the reducer.
+ *
+ *  @see op_xor
+ *  @see reducer
+ *  @see ReducersXor
+ *
+ *  @ingroup ReducersXor
+ */
+template <typename Type>
+class reducer_opxor : public reducer< op_xor<Type, true> >
+{
+    typedef reducer< op_xor<Type, true> > base;
+    using base::view;
+
+  public:
+    /// The view type for the reducer.
+    typedef typename base::view_type        view_type;
+    
+    /// The view’s rhs proxy type.
+    typedef typename view_type::rhs_proxy   rhs_proxy;
+    
+    /// The view type for the reducer.
+    typedef view_type                       View;
+
+    /// The monoid type for the reducer.
+    typedef typename base::monoid_type      Monoid;
+    
+    /** @name Constructors
+     */
+    //@{
+    
+    /** Default (identity) constructor.
+     *
+     * Constructs the wrapper with the default initial value of `Type()`.
+     */
+    reducer_opxor() {}
+
+    /** Value constructor.
+     *
+     *  Constructs the wrapper with a specified initial value.
+     */
+    explicit reducer_opxor(const Type& initial_value) : base(initial_value) {}
+    
+    //@}
+
+    /** @name Forwarded functions
+     *  @details Functions that update the contained accumulator variable are
+     *  simply forwarded to the contained @ref op_and_view. */
+    //@{
+
+    /// @copydoc op_xor_view::operator^=(const Type&)
+    reducer_opxor& operator^=(const Type& x)
+    {
+        view() ^= x; return *this; 
+    }
+    
+    // The legacy definition of reducer_opxor::operator^() has different
+    // behavior and a different return type than this definition. The legacy
+    // version is defined as a member function, so this new version is defined
+    // as a free function to give it a different signature, so that they won’t 
+    // end up sharing a single object file entry.
+
+    /// @copydoc op_xor_view::operator^(const Type&) const
+    friend rhs_proxy operator^(const reducer_opxor& r, const Type& x)
+    { 
+        return r.view() ^ x; 
+    }
+
+    /// @copydoc op_and_view::operator=(const rhs_proxy&)
+    reducer_opxor& operator=(const rhs_proxy& temp)
+    {
+        view() = temp; return *this; 
+    }
+    //@}
+
+    /** @name Dereference
+     *  @details Dereferencing a wrapper is a no-op. It simply returns the
+     *  wrapper. Combined with the rule that the wrapper forwards view
+     *  operations to its contained view, this means that view operations can
+     *  be written the same way on reducers and wrappers, which is convenient
+     *  for incrementally converting old code using wrappers to use reducers
+     *  instead. That is:
+     *
+     *      reducer< op_and<int> > r;
+     *      *r &= a;    // *r returns the view
+     *                  // operator &= is a view member function
+     *
+     *      reducer_opand<int> w;
+     *      *w &= a;    // *w returns the wrapper
+     *                  // operator &= is a wrapper member function that
+     *                  // calls the corresponding view function
+     */
+    //@{
+    reducer_opxor&       operator*()       { return *this; }
+    reducer_opxor const& operator*() const { return *this; }
+
+    reducer_opxor*       operator->()       { return this; }
+    reducer_opxor const* operator->() const { return this; }
+    //@}
+    
+    /** @name Upcast
+     *  @details In Cilk library 0.9, reducers were always cache-aligned. In
+     *  library  1.0, reducer cache alignment is optional. By default, reducers
+     *  are unaligned (i.e., just naturally aligned), but legacy wrappers
+     *  inherit from cache-aligned reducers for binary compatibility.
+     *
+     *  This means that a wrapper will automatically be upcast to its aligned
+     *  reducer base class. The following conversion operators provide
+     *  pseudo-upcasts to the corresponding unaligned reducer class.
+     */
+    //@{
+    operator reducer< op_xor<Type, false> >& ()
+    {
+        return *reinterpret_cast< reducer< op_xor<Type, false> >* >(this);
+    }
+    operator const reducer< op_xor<Type, false> >& () const
+    {
+        return *reinterpret_cast< const reducer< op_xor<Type, false> >* >(this);
+    }
+    //@}
+    
+};
+
+/// @cond internal
+/** Metafunction specialization for reducer conversion.
+ *
+ *  This specialization of the @ref legacy_reducer_downcast template class 
+ *  defined in reducer.h causes the `reducer< op_xor<Type> >` class to have an 
+ *  `operator reducer_opxor<Type>& ()` conversion operator that statically
+ *  downcasts the `reducer<op_xor>` to the corresponding `reducer_opxor` type.
+ *  (The reverse conversion, from `reducer_opxor` to `reducer<op_xor>`, is just
+ *  an upcast, which is provided for free by the language.)
+ *
+ *  @ingroup ReducersXor
+ */
+template <typename Type, bool Align>
+struct legacy_reducer_downcast<reducer<op_xor<Type, Align> > >
+{
+    typedef reducer_opxor<Type> type;
+};
+/// @endcond
+
+} // namespace cilk
+
+#endif /* __cplusplus */
+
+
+/** @ingroup ReducersXor
+ */
+//@{
+
+/** @name C language reducer macros
+ *
+ *  These macros are used to declare and work with op_xor reducers in C code.
+ *
+ *  @see @ref page_reducers_in_c
+ */
+ //@{
+__CILKRTS_BEGIN_EXTERN_C
+
+/** Opxor reducer type name.
+ *
+ *  This macro expands into the identifier which is the name of the op_xor
+ *  reducer type for a specified numeric type.
+ *
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying
+ *              the type of the reducer.
+ *
+ *  @see @ref reducers_c_predefined
+ *  @see ReducersXor
+ */
+#define CILK_C_REDUCER_OPXOR_TYPE(tn)                                         \
+    __CILKRTS_MKIDENT(cilk_c_reducer_opxor_,tn)
+
+/** Declare an op_xor reducer object.
+ *
+ *  This macro expands into a declaration of an op_xor reducer object for a
+ *  specified numeric type. For example:
+ *
+ *      CILK_C_REDUCER_OPXOR(my_reducer, ulong, 0);
+ *
+ *  @param  obj The variable name to be used for the declared reducer object.
+ *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying
+ *              the type of the reducer.
+ *  @param  v   The initial value for the reducer. (A value which can be
+ *              assigned to the numeric type represented by @a tn.)
+ *
+ *  @see @ref reducers_c_predefined
+ *  @see ReducersXor
+ */
+#define CILK_C_REDUCER_OPXOR(obj,tn,v)                                        \
+    CILK_C_REDUCER_OPXOR_TYPE(tn) obj =                                       \
+        CILK_C_INIT_REDUCER(_Typeof(obj.value),                               \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_opxor_reduce_,tn),   \
+                        __CILKRTS_MKIDENT(cilk_c_reducer_opxor_identity_,tn), \
+                        __cilkrts_hyperobject_noop_destroy, v)
+
+/// @cond internal
+
+/** Declare the op_xor reducer functions for a numeric type.
+ *
+ *  This macro expands into external function declarations for functions which
+ *  implement the reducer functionality for the op_xor reducer type for a
+ *  specified numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer
+ *              type name, function names, etc.
+ */
+#define CILK_C_REDUCER_OPXOR_DECLARATION(t,tn)                             \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPXOR_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opxor,tn,l,r);         \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opxor,tn);
+/** Define the op_xor reducer functions for a numeric type.
+ *
+ *  This macro expands into function definitions for functions which implement
+ *  the reducer functionality for the op_xor reducer type for a specified 
+ *  numeric type.
+ *
+ *  @param  t   The value type of the reducer.
+ *  @param  tn  The value “type name” identifier, used to construct the reducer
+ *              type name, function names, etc.
+ */
+#define CILK_C_REDUCER_OPXOR_DEFINITION(t,tn)                              \
+    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPXOR_TYPE(tn);       \
+    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opxor,tn,l,r)          \
+        { *(t*)l ^= *(t*)r; }                                              \
+    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opxor,tn)            \
+        { *(t*)v = 0; }
+//@{
+/** @def CILK_C_REDUCER_OPXOR_INSTANCE 
+ *  @brief Declare or define implementation functions for a reducer type.
+ *
+ *  In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS`
+ *  will be defined, and this macro will generate reducer implementation
+ *  functions. Everywhere else, `CILK_C_DEFINE_REDUCERS` will be undefined, and
+ *  this macro will expand into external declarations for the functions.
+ */
+#ifdef CILK_C_DEFINE_REDUCERS
+#   define CILK_C_REDUCER_OPXOR_INSTANCE(t,tn)  \
+        CILK_C_REDUCER_OPXOR_DEFINITION(t,tn)
+#else
+#   define CILK_C_REDUCER_OPXOR_INSTANCE(t,tn)  \
+        CILK_C_REDUCER_OPXOR_DECLARATION(t,tn)
+#endif
+//@}
+
+/*  Declare or define an instance of the reducer type and its functions for each 
+ *  numeric type.
+ */
+CILK_C_REDUCER_OPXOR_INSTANCE(char,                 char)
+CILK_C_REDUCER_OPXOR_INSTANCE(unsigned char,        uchar)
+CILK_C_REDUCER_OPXOR_INSTANCE(signed char,          schar)
+CILK_C_REDUCER_OPXOR_INSTANCE(wchar_t,              wchar_t)
+CILK_C_REDUCER_OPXOR_INSTANCE(short,                short)
+CILK_C_REDUCER_OPXOR_INSTANCE(unsigned short,       ushort)
+CILK_C_REDUCER_OPXOR_INSTANCE(int,                  int)
+CILK_C_REDUCER_OPXOR_INSTANCE(unsigned int,         uint)
+CILK_C_REDUCER_OPXOR_INSTANCE(unsigned int,         unsigned) /* alternate name */
+CILK_C_REDUCER_OPXOR_INSTANCE(long,                 long)
+CILK_C_REDUCER_OPXOR_INSTANCE(unsigned long,        ulong)
+CILK_C_REDUCER_OPXOR_INSTANCE(long long,            longlong)
+CILK_C_REDUCER_OPXOR_INSTANCE(unsigned long long,   ulonglong)
+
+//@endcond
+
+__CILKRTS_END_EXTERN_C
+
+//@}
+
+//@}
+
+#endif /*  REDUCER_OPXOR_H_INCLUDED */
diff --git a/libcilkrts/include/cilk/reducer_ostream.h b/libcilkrts/include/cilk/reducer_ostream.h
new file mode 100644 (file)
index 0000000..d9addee
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * reducer_ostream.h
+ *
+ * Purpose: Hyper-object to write to 'std::ostream's
+ *
+ * Classes: reducer_ostream
+ *
+ * Description:
+ * ============
+ * Output streams ('std::ostream's) are a convenient means of writing text to
+ * files, the user console, or sockets.  In a serial program, text is written
+ * to an ostream in a specific, logical order.  For example, computing while
+ * traversing a data structure and printing them to an 'ostream' will result
+ * in the values being printed in the order of traversal.  In a parallel
+ * version of the same program, however, different parts of the data structure
+ * may be traversed in a different order, resulting in a non-deterministic
+ * ordering of the stream.  Worse, multiple strands may write to the same
+ * stream simultaneously, resulting in a data race.  Replacing the
+ * 'std::ostream' with a 'cilk::reducer_ostream' will solve both problems: Data
+ * will appeaer in the stream in the same order as it would for the serial
+ * program, and there will be no races (no locks) on the common stream.
+ *
+ * Usage Example:
+ * ==============
+ * Assume we wish to traverse an array of objects, performing an operation on
+ * each object and writing the result to a file.  Without a reducer_ostream,
+ * we have a race on the 'output' file stream:
+ *..
+ *  void compute(std::ostream& os, double x)
+ *  {
+ *      // Perform some significant computation and print the result:
+ *      os << std::asin(x);
+ *  }
+ *
+ *  int test()
+ *  {
+ *      const std::size_t ARRAY_SIZE = 1000000;
+ *      extern double myArray[ARRAY_SIZE];
+ *
+ *      std::ofstream output("output.txt");
+ *      cilk_for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
+ *      {
+ *          compute(output, myArray[i]);
+ *      }
+ *
+ *      return 0;
+ *  }
+ *..
+ * The race is solved by using a reducer_ostream to proxy the 'output' file:
+ *..
+ *  void compute(cilk::reducer_ostream& os, double x)
+ *  {
+ *      // Perform some significant computation and print the result:
+ *      *os << std::asin(x);
+ *  }
+ *
+ *  int test()
+ *  {
+ *      const std::size_t ARRAY_SIZE = 1000000;
+ *      extern double myArray[ARRAY_SIZE];
+ *
+ *      std::ofstream output("output.txt");
+ *      cilk::reducer_ostream hyper_output(output);
+ *      cilk_for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
+ *      {
+ *          compute(hyper_output, myArray[i]);
+ *      }
+ *
+ *      return 0;
+ *  }
+ *..
+ *
+ * Limitations:
+ * ============
+ * There are two possible values for the formatting flags immediately after a
+ * 'cilk_spawn' statement: they may either have the value that was set by the
+ * spawn function, or they may have default values.  Because of
+ * non-determinism in the processor scheduling, there is no way to determine
+ * which it will be.  Similarly, the formatting flags after a 'cilk_sync' may
+ * or may not have the same value as before the sync.  Therefore, one must use
+ * a disciplined coding style to avoid formatting errors.  There are two
+ * approaches to mitigating the problem: The first is to eliminate the
+ * difference between the two possible outcomes by ensuring that the spawned
+ * function always returns the flags to their initial state:
+ *..
+ *  void compute(cilk::reducer_ostream& os, double x)
+ *  {
+ *      // Perform some significant computation and print the result:
+ *      int saveprec = os.precision(5);
+ *      os << std::asin(x);
+ *      os.precision(saveprec);
+ *  }
+ *..
+ * The second approach is to write your streaming operations such that they
+ * don't depend on the previous state of the formatting flags by setting any
+ * important flags before every block of output:
+ *..
+ *      cilk_spawn compute(hyper_output, value);
+ *
+ *      hyper_output->precision(2);  // Don't depend on previous precision
+ *      *hyper_output << f();
+ *      *hyper_output << g();
+ *..
+ * Another concern is memory usage.  A reducer_ostream will buffer as much text
+ * as necessary to ensure that the order of output matches that of the serial
+ * version of the program.  If all spawn branches perform an equal amount of
+ * output, then one can expect that half of the output before a sync will be
+ * buffered in memory.  This hyperobject is therefore not well suited for
+ * serializing very large quantities of text output.
+ */
+
+#ifndef REDUCER_OSTREAM_H_INCLUDED
+#define REDUCER_OSTREAM_H_INCLUDED
+
+#include <cilk/reducer.h>
+#include <iostream>
+#include <sstream>
+
+namespace cilk {
+
+/**
+ * @brief Class 'reducer_ostream' is the representation of a hyperobject for
+ * output text streaming.
+ */
+class reducer_ostream
+{
+public:
+    /// Internal representation of the per-strand view of the data for reducer_ostream
+    class View: public std::ostream
+    {
+    public:
+        /// Type of the std::stream reducer_ostream is based on
+        typedef std::ostream Base;
+
+        friend class reducer_ostream;
+
+        View():
+            std::ostream(0)
+        {
+            Base::rdbuf(&strbuf_);
+        };
+
+    private:
+        void use_ostream (const std::ostream &os)
+        {
+            Base::rdbuf(os.rdbuf());
+            Base::flags(os.flags());       // Copy formatting flags
+            Base::setstate(os.rdstate());  // Copy error state
+        }
+
+    private:
+        std::stringbuf  strbuf_;
+    };
+
+public:
+    /// Definition of data view, operation, and identity for reducer_ostream
+    struct Monoid: monoid_base< View >
+    {
+        static void reduce (View *left, View *right);
+    };
+
+private:
+    // Hyperobject to serve up views
+    reducer<Monoid> imp_;
+
+    // Methods that provide the API for the reducer
+public:
+
+    // Construct an initial 'reducer_ostream' from an 'std::ostream'.  The
+    // specified 'os' stream is used as the eventual destination for all
+    // text streamed to this hyperobject.
+    explicit reducer_ostream(const std::ostream &os);
+
+    // Return a modifiable reference to the underlying 'ostream' object.
+    std::ostream& get_reference();
+
+    /**
+     * Append data from some type to the reducer_ostream
+     *
+     * @param v Value to be appended to the reducer_ostream
+     */
+    template<typename T>
+    std::ostream &
+    operator<< (const T &v)
+    {
+        return imp_.view() << v;
+    }
+
+    /**
+     * Append data from a std::ostream to the reducer_ostream
+     *
+     * @param _Pfn std::ostream to copy from
+     */
+    std::ostream &
+    operator<< (std::ostream &(*_Pfn)(std::ostream &))
+    {
+        View &v = imp_.view();
+
+        return ((*_Pfn)(v));
+    }
+
+    reducer_ostream&       operator*()       { return *this; }
+    reducer_ostream const& operator*() const { return *this; }
+
+    reducer_ostream*       operator->()       { return this; }
+    reducer_ostream const* operator->() const { return this; }
+};
+
+
+// -------------------------------------------
+// class reducer_ostream::Monoid
+// -------------------------------------------
+
+/**
+ * Appends string from "right" reducer_basic_string onto the end of
+ * the "left". When done, the "right" reducer_basic_string is empty.
+ */
+void
+reducer_ostream::Monoid::reduce(View *left, View *right)
+{
+    left->operator<< (&right->strbuf_);
+}
+
+// --------------------------
+// class reducer_ostream
+// --------------------------
+
+/**
+ * Construct a reducer_ostream which will write to the specified std::ostream
+ *
+ * @param os std::ostream to write to
+ */
+inline
+reducer_ostream::reducer_ostream(const std::ostream &os) :
+    imp_()
+{
+    View &v = imp_.view();
+
+    v.use_ostream(os);
+}
+
+/**
+ * Get a reference to the std::ostream
+ */
+inline
+std::ostream &
+reducer_ostream::get_reference()
+{
+    View &v = imp_.view();
+
+    return v;
+}
+
+} // namespace cilk
+
+#endif //  REDUCER_OSTREAM_H_INCLUDED
+
diff --git a/libcilkrts/include/cilk/reducer_string.h b/libcilkrts/include/cilk/reducer_string.h
new file mode 100644 (file)
index 0000000..0d70dd8
--- /dev/null
@@ -0,0 +1,729 @@
+/*  reducer_string.h                  -*- C++ -*-
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file reducer_string.h
+ *
+ *  @brief Defines classes for doing parallel string creation by appending.
+ *
+ *  @ingroup ReducersString
+ *
+ *  @see ReducersString
+ */
+
+#ifndef REDUCER_STRING_H_INCLUDED
+#define REDUCER_STRING_H_INCLUDED
+
+#include <cilk/reducer.h>
+#include <string>
+#include <list>
+
+/** @defgroup ReducersString String Reducers
+ *
+ *  String reducers allow the creation of a string by concatenating a set of 
+ *  strings or characters in parallel.
+ *
+ *  @ingroup Reducers
+ *
+ *  You should be familiar with @ref pagereducers "Cilk reducers", described in
+ *  file reducers.md, and particularly with @ref reducers_using, before trying
+ *  to use the information in this file.
+ *
+ *  @section redstring_usage Usage Example
+ *
+ *      vector<Data> data;
+ *      void expensive_string_computation(const Data& x, string& s);
+ *      cilk::reducer<cilk::op_string> r;
+ *      cilk_for (int i = 0; i != data.size(); ++i) {
+ *          string temp;
+ *          expensive_string_computation(data[i], temp);
+ *          *r += temp;
+ *      }
+ *      string result;
+ *      r.move_out(result);
+ *
+ *  @section redstring_monoid The Monoid
+ *
+ *  @subsection redstring_monoid_values Value Set
+ *
+ *  The value set of a string reducer is the set of values of the class
+ *  `std::basic_string<Char, Traits, Alloc>`, which we refer to as “the
+ *  reducer’s string type”.
+ *
+ *  @subsection redstring_monoid_operator Operator
+ *
+ *  The operator of a string reducer is the string concatenation operator, 
+ *  defined by the “`+`” binary operator on the reducer’s string type.
+ *
+ *  @subsection redstring_monoid_identity Identity
+ *
+ *  The identity value of a string reducer is the empty string, which is the 
+ *  value of the expression
+ *  `std::basic_string<Char, Traits, Alloc>([allocator])`.
+ *
+ *  @section redstring_operations Operations
+ *
+ *  In the operation descriptions below, the type name `String` refers to the
+ *  reducer’s string type, `std::basic_string<Char, Traits, Alloc>`.
+ *
+ *  @subsection redstring_constructors Constructors
+ *
+ *  Any argument list which is valid for a `std::basic_string` constructor is
+ *  valid for a string reducer constructor. The usual move-in constructor is
+ *  also provided:
+ *
+ *      reducer(move_in(String& variable))
+ *
+ *  @subsection redstring_get_set Set and Get
+ *
+ *      r.set_value(const String& value)
+ *      const String& = r.get_value() const
+ *      r.move_in(String& variable)
+ *      r.move_out(String& variable)
+ *
+ *  @subsection redstring_initial Initial Values
+ *
+ *  A string reducer with no constructor arguments, or with only an allocator
+ *  argument, will initially contain the identity value, an empty string.
+ *
+ *  @subsection redstring_view_ops View Operations
+ *
+ *      *r += a
+ *      r->append(a)
+ *      r->append(a, b)
+ *      r->push_back(a)
+ *
+ *  These operations on string reducer views are the same as the corresponding
+ *  operations on strings.
+ *
+ *  @section redstring_performance Performance Considerations
+ *
+ *  String reducers work by creating a string for each view, collecting those
+ *  strings in a list, and then concatenating them into a single result string
+ *  at the end of the computation. This last step takes place in serial code,
+ *  and necessarily takes time proportional to the length of the result string.
+ *  Thus, a parallel string reducer cannot actually speed up the time spent
+ *  directly creating the string. This trivial example would probably be slower
+ *  (because of reducer overhead) than the corresponding serial code:
+ *
+ *      vector<string> a;
+ *      reducer<op_string> r;
+ *      cilk_for (int i = 0; i != a.length(); ++i) {
+ *          *r += a[i];
+ *      }
+ *      string result;
+ *      r.move_out(result);
+ *
+ *  What a string reducer _can_ do is to allow the _remainder_ of the
+ *  computation to be done in parallel, without having to worry about managing
+ *  the string computation.
+ *
+ *  The strings for new views are created (by the view identity constructor)
+ *  using the same allocator as the string that was created when the reducer 
+ *  was constructed. Note that this allocator is determined when the reducer is 
+ *  constructed. The following two examples may have very different behavior:
+ *
+ *      string<Char, Traits, Allocator> a_string;
+ *
+ *      reducer< op_string<Char, Traits, Allocator> reducer1(move_in(a_string));
+ *      ... parallel computation ...
+ *      reducer1.move_out(a_string);
+ *
+ *      reducer< op_string<Char, Traits, Allocator> reducer2;
+ *      reducer2.move_in(a_string);
+ *      ... parallel computation ...
+ *      reducer2.move_out(a_string);
+ *
+ *  *   `reducer1` will be constructed with the same allocator as `a_string`, 
+ *      because the string was specified in the constructor. The `move_in`
+ *      and `move_out` can therefore be done with a `swap` in constant time.
+ *  *   `reducer2` will be constructed with a _default_ allocator of type
+ *      `Allocator`, which may not be the same as the allocator of `a_string`.
+ *      Therefore, the `move_in` and `move_out` may have to be done with a copy
+ *      in _O(N)_ time.
+ *
+ *  (All instances of an allocator type with no internal state (like
+ *  `std::allocator`) are “the same”. You only need to worry about the “same
+ *  allocator” issue when you create string reducers with custom allocator
+ *  types.)
+ *
+ *  @section redstring_types Type and Operator Requirements
+ *
+ *  `std::basic_string<Char, Traits, Alloc>` must be a valid type.
+*/
+
+namespace cilk {
+
+/** @ingroup ReducersString */
+//@{
+
+/** The string append reducer view class.
+ *
+ *  This is the view class for reducers created with
+ *  `cilk::reducer< cilk::op_basic_string<Type, Traits, Allocator> >`. It holds
+ *  the accumulator variable for the reduction, and allows only append
+ *  operations to be performed on it.
+ *
+ *  @note   The reducer “dereference” operation (`reducer::operator *()`) 
+ *          yields a reference to the view. Thus, for example, the view class’s
+ *          `append` operation would be used in an expression like
+ *          `r->append(a)`, where `r` is a string append reducer variable.
+ *
+ *  @tparam Char        The string element type (not the string type).
+ *  @tparam Traits      The character traits type.
+ *  @tparam Alloc       The string allocator type.
+ *
+ *  @see ReducersString
+ *  @see op_basic_string
+ */
+template<typename Char, typename Traits, typename Alloc>
+class op_basic_string_view
+{
+    typedef std::basic_string<Char, Traits, Alloc>  string_type;
+    typedef std::list<string_type>                  list_type;
+    typedef typename string_type::size_type         size_type;
+
+    // The view's value is represented by a list of strings and a single 
+    // string. The value is the concatenation of the strings in the list with
+    // the single string at the end. All string operations apply to the single
+    // string; reduce operations cause lists of partial strings from multiple
+    // strands to be combined.
+    //
+    mutable string_type                             m_string;
+    mutable list_type                               m_list;
+
+    // Before returning the value of the reducer, concatenate all the strings 
+    // in the list with the single string.
+    //
+    void flatten() const
+    {
+        if (m_list.empty()) return;
+
+        typename list_type::iterator i;
+
+        size_type len = m_string.size();
+        for (i = m_list.begin(); i != m_list.end(); ++i)
+            len += i->size();
+
+        string_type result(get_allocator());
+        result.reserve(len);
+
+        for (i = m_list.begin(); i != m_list.end(); ++i)
+            result += *i;
+        m_list.clear();
+
+        result += m_string;
+        result.swap(m_string);
+    }
+
+public:
+
+    /** @name Monoid support.
+     */
+    //@{
+
+    /// Required by @ref monoid_with_view
+    typedef string_type value_type;
+
+    /// Required by @ref op_string
+    Alloc get_allocator() const
+    {
+        return m_string.get_allocator();
+    }
+
+    /** Reduction operation.
+     *
+     *  This function is invoked by the @ref op_basic_string monoid to combine
+     *  the views of two strands when the right strand merges with the left 
+     *  one. It appends the value contained in the right-strand view to the 
+     *  value contained in the left-strand view, and leaves the value in the
+     *  right-strand view undefined.
+     *
+     *  @param  right   A pointer to the right-strand view. (`this` points to
+     *                  the left-strand view.)
+     *
+     *  @note   Used only by the @ref op_basic_string monoid to implement the
+     *          monoid reduce operation.
+     */
+    void reduce(op_basic_string_view* right)
+    {
+        if (!right->m_string.empty() || !right->m_list.empty()) {
+            // (list, string) + (right_list, right_string) =>
+            //      (list + {string} + right_list, right_string)
+            if (!m_string.empty()) {
+                // simulate m_list.push_back(std::move(m_string))
+                m_list.push_back(string_type(get_allocator()));
+                m_list.back().swap(m_string);
+            }
+            m_list.splice(m_list.end(), right->m_list);
+            m_string.swap(right->m_string);
+        }
+    }
+
+    //@}
+
+    /** @name Pass constructor arguments through to the string constructor.
+     */
+    //@{
+
+    op_basic_string_view() : m_string() {}
+
+    template <typename T1>
+    op_basic_string_view(const T1& x1) : m_string(x1) {}
+
+    template <typename T1, typename T2>
+    op_basic_string_view(const T1& x1, const T2& x2) : m_string(x1, x2) {}
+
+    template <typename T1, typename T2, typename T3>
+    op_basic_string_view(const T1& x1, const T2& x2, const T3& x3) : m_string(x1, x2, x3) {}
+
+    template <typename T1, typename T2, typename T3, typename T4>
+    op_basic_string_view(const T1& x1, const T2& x2, const T3& x3, const T4& x4) :
+        m_string(x1, x2, x3, x4) {}
+
+    //@}
+
+    /** Move-in constructor.
+     */
+    explicit op_basic_string_view(move_in_wrapper<value_type> w)
+        : m_string(w.value().get_allocator())
+    {
+        m_string.swap(w.value());
+    }
+
+    /** @name @ref reducer support.
+     */
+    //@{
+
+    void view_move_in(string_type& s)
+    {
+        m_list.clear();
+        if (m_string.get_allocator() == s.get_allocator())
+            // Equal allocators. Do a (fast) swap.
+            m_string.swap(s);
+        else
+            // Unequal allocators. Do a (slow) copy.
+            m_string = s;
+        s.clear();
+    }
+
+    void view_move_out(string_type& s)
+    {
+        flatten();
+        if (m_string.get_allocator() == s.get_allocator())
+            // Equal allocators.  Do a (fast) swap.
+            m_string.swap(s);
+        else
+            // Unequal allocators.  Do a (slow) copy.
+            s = m_string;
+        m_string.clear();
+    }
+
+    void view_set_value(const string_type& s) 
+        { m_list.clear(); m_string = s; }
+
+    string_type const& view_get_value()     const 
+        { flatten(); return m_string; }
+
+    string_type      & view_get_reference()       
+        { flatten(); return m_string; }
+
+    string_type const& view_get_reference() const 
+        { flatten(); return m_string; }
+
+    //@}
+
+    /** @name View modifier operations.
+     *
+     *  @details These simply wrap the corresponding operations on the underlying string.
+     */
+    //@{
+
+    template <typename T>
+    op_basic_string_view& operator +=(const T& x)
+        { m_string += x; return *this; }
+
+    template <typename T1>
+    op_basic_string_view& append(const T1& x1)
+        { m_string.append(x1); return *this; }
+
+    template <typename T1, typename T2>
+    op_basic_string_view& append(const T1& x1, const T2& x2)
+        { m_string.append(x1, x2); return *this; }
+
+    template <typename T1, typename T2, typename T3>
+    op_basic_string_view& append(const T1& x1, const T2& x2, const T3& x3)
+        { m_string.append(x1, x2, x3); return *this; }
+
+    void push_back(const Char x) { m_string.push_back(x); }
+
+    //@}
+};
+
+
+/** String append monoid class. Instantiate the cilk::reducer template class
+ *  with an op_basic_string monoid to create a string append reducer class. For
+ *  example, to concatenate a collection of standard strings:
+ *
+ *      cilk::reducer< cilk::op_basic_string<char> > r;
+ *
+ *  @tparam Char    The string element type (not the string type).
+ *  @tparam Traits  The character traits type.
+ *  @tparam Alloc   The string allocator type.
+ *  @tparam Align   If `false` (the default), reducers instantiated on this
+ *                  monoid will be naturally aligned (the Cilk library 1.0
+ *                  behavior). If `true`, reducers instantiated on this monoid
+ *                  will be cache-aligned for binary compatibility with 
+ *                  reducers in Cilk library version 0.9.
+ *
+ *  @see ReducersString
+ *  @see op_basic_string_view
+ *  @see reducer_basic_string
+ *  @see op_string
+ *  @see op_wstring
+ */
+template<typename Char,
+         typename Traits = std::char_traits<Char>,
+         typename Alloc = std::allocator<Char>,
+         bool     Align = false>
+class op_basic_string : 
+    public monoid_with_view< op_basic_string_view<Char, Traits, Alloc>, Align >
+{
+    typedef monoid_with_view< op_basic_string_view<Char, Traits, Alloc>, Align >
+            base;
+    Alloc m_allocator;
+
+public:
+
+    /** View type of the monoid.
+     */
+    typedef typename base::view_type view_type;
+
+    /** Constructor.
+     *
+     *  There is no default constructor for string monoids, because the
+     *  allocator must always be specified.
+     *
+     *  @param  allocator   The list allocator to be used when
+     *                      identity-constructing new views.
+     */
+    op_basic_string(const Alloc& allocator = Alloc()) : m_allocator(allocator)
+    {}
+
+    /** Create an identity view.
+     *
+     *  String view identity constructors take the string allocator as an
+     *  argument.
+     *
+     *  @param v    The address of the uninitialized memory in which the view
+     *              will be constructed.
+     */
+    void identity(view_type *v) const { ::new((void*) v) view_type(m_allocator); }
+
+    /** @name Construct functions
+     *
+     *  A string append reduction monoid must have a copy of the allocator of
+     *  the leftmost view’s string, so that it can use it in the `identity`
+     *  operation. This, in turn, requires that string reduction monoids have a
+     *  specialized `construct()` function.
+     *
+     *  All string reducer monoid `construct()` functions first construct the
+     *  leftmost view, using the arguments that were passed in from the reducer
+     *  constructor. They then call the view’s `get_allocator()` function to
+     *  get the string allocator from the string in the leftmost view, and pass
+     *  that to the monoid constructor.
+     */
+    //@{
+
+    static void construct(op_basic_string* monoid, view_type* view)
+        { provisional( new ((void*)view) view_type() ).confirm_if(
+            new ((void*)monoid) op_basic_string(view->get_allocator()) ); }
+
+    template <typename T1>
+    static void construct(op_basic_string* monoid, view_type* view, const T1& x1)
+        { provisional( new ((void*)view) view_type(x1) ).confirm_if(
+            new ((void*)monoid) op_basic_string(view->get_allocator()) ); }
+
+    template <typename T1, typename T2>
+    static void construct(op_basic_string* monoid, view_type* view, const T1& x1, const T2& x2)
+        { provisional( new ((void*)view) view_type(x1, x2) ).confirm_if(
+            new ((void*)monoid) op_basic_string(view->get_allocator()) ); }
+
+    template <typename T1, typename T2, typename T3>
+    static void construct(op_basic_string* monoid, view_type* view, const T1& x1, const T2& x2,
+                            const T3& x3)
+        { provisional( new ((void*)view) view_type(x1, x2, x3) ).confirm_if(
+            new ((void*)monoid) op_basic_string(view->get_allocator()) ); }
+
+    template <typename T1, typename T2, typename T3, typename T4>
+    static void construct(op_basic_string* monoid, view_type* view, const T1& x1, const T2& x2,
+                            const T3& x3, const T4& x4)
+        { provisional( new ((void*)view) view_type(x1, x2, x3, x4) ).confirm_if(
+            new ((void*)monoid) op_basic_string(view->get_allocator()) ); }
+
+    //@}
+};
+
+
+/** Convenience typedef for 8-bit strings
+ */
+typedef op_basic_string<char> op_string;
+    
+/** Convenience typedef for 16-bit strings
+ */
+typedef op_basic_string<wchar_t> op_wstring;
+
+
+/** Deprecated string append reducer class.
+ *
+ *  reducer_basic_string is the same as @ref reducer<@ref op_basic_string>,
+ *  except that reducer_basic_string is a proxy for the contained view, so that
+ *  accumulator variable update operations can be applied directly to the
+ *  reducer. For example, a value is appended to a `reducer<%op_basic_string>`
+ *  with `r->push_back(a)`, but a value can be appended to  a `%reducer_opand`
+ *  with `r.push_back(a)`.
+ *
+ *  @deprecated Users are strongly encouraged to use `reducer<monoid>`
+ *              reducers rather than the old wrappers like reducer_basic_string. 
+ *              The `reducer<monoid>` reducers show the reducer/monoid/view
+ *              architecture more clearly, are more consistent in their
+ *              implementation, and present a simpler model for new
+ *              user-implemented reducers.
+ *
+ *  @note   Implicit conversions are provided between `%reducer_basic_string` 
+ *          and `reducer<%op_basic_string>`. This allows incremental code
+ *          conversion: old code that used `%reducer_basic_string` can pass a
+ *          `%reducer_basic_string` to a converted function that now expects a
+ *          pointer or reference to a `reducer<%op_basic_string>`, and vice
+ *          versa.
+ *
+ *  @tparam Char        The string element type (not the string type).
+ *  @tparam Traits      The character traits type.
+ *  @tparam Alloc       The string allocator type.
+ *
+ *  @see op_basic_string
+ *  @see reducer
+ *  @see ReducersString
+ */
+template<typename Char,
+         typename Traits = std::char_traits<Char>,
+         typename Alloc = std::allocator<Char> >
+class reducer_basic_string : 
+    public reducer< op_basic_string<Char, Traits, Alloc, true> >
+{
+    typedef reducer< op_basic_string<Char, Traits, Alloc, true> > base;
+    using base::view;
+public:
+
+    /// The reducer’s string type.
+    typedef typename base::value_type       string_type;
+
+    /// The reducer’s primitive component type.
+    typedef Char                            basic_value_type;
+
+    /// The string size type.
+    typedef typename string_type::size_type size_type;
+
+    /// The view type for the reducer.
+    typedef typename base::view_type        View;
+
+    /// The monoid type for the reducer.
+    typedef typename base::monoid_type      Monoid;
+
+
+    /** @name Constructors
+     */
+    //@{
+    
+    /** @name Forward constructor calls to the base class.
+     *
+     *  All basic_string constructor forms are supported.
+     */
+    //@{
+    reducer_basic_string() {}
+
+    template <typename T1>
+    reducer_basic_string(const T1& x1) : 
+        base(x1) {}
+
+    template <typename T1, typename T2>
+    reducer_basic_string(const T1& x1, const T2& x2) : 
+        base(x1, x2) {}
+
+    template <typename T1, typename T2, typename T3>
+    reducer_basic_string(const T1& x1, const T2& x2, const T3& x3) : 
+        base(x1, x2, x3) {}
+
+    template <typename T1, typename T2, typename T3, typename T4>
+    reducer_basic_string(const T1& x1, const T2& x2, const T3& x3, const T4& x4) :
+        base(x1, x2, x3, x4) {}
+    //@}
+
+    /** Allow mutable access to the string within the current view.
+     *
+     *  @warning    If this method is called before the parallel calculation is 
+     *              complete, the string returned by this method will be a
+     *              partial result.
+     *
+     *  @returns    A mutable reference to the string within the current view.
+     */
+    string_type &get_reference() 
+        { return view().view_get_reference(); }
+
+    /** Allow read-only access to the string within the current view.
+     *
+     *  @warning    If this method is called before the parallel calculation is
+     *              complete, the string returned by this method will be a
+     *              partial result.
+     *
+     *  @returns    A const reference to the string within the current view.
+     */
+    string_type const &get_reference() const 
+        { return view().view_get_reference(); }
+
+    /** @name Append to the string.
+     *
+     *  These operations are simply forwarded to the view.
+     */
+    //@{
+    void append(const Char *ptr)
+        { view().append(ptr); }
+    void append(const Char *ptr, size_type count)
+        { view().append(ptr, count); }
+    void append(const string_type &str, size_type offset, size_type count)
+        { view().append(str, offset, count); }
+    void append(const string_type &str)
+        { view().append(str); }
+    void append(size_type count, Char ch)
+        { view().append(count, ch); }
+
+    // Append to the string
+    reducer_basic_string<Char, Traits, Alloc> &operator+=(Char ch)
+        { view() += ch; return *this; }
+    reducer_basic_string<Char, Traits, Alloc> &operator+=(const Char *ptr)
+        { view() += ptr; return *this; }
+    reducer_basic_string<Char, Traits, Alloc> &operator+=(const string_type &right)
+        { view() += right; return *this; }
+    //@}
+
+    /** @name Dereference
+     *  @details Dereferencing a wrapper is a no-op. It simply returns the
+     *  wrapper. Combined with the rule that the wrapper forwards view
+     *  operations to its contained view, this means that view operations can
+     *  be written the same way on reducers and wrappers, which is convenient
+     *  for incrementally converting old code using wrappers to use reducers
+     *  instead. That is:
+     *
+     *      reducer<op_string> r;
+     *      r->push_back(a);    // r-> returns the view
+     *                          // push_back() is a view member function
+     *
+     *      reducer_string w;
+     *      w->push_back(a);    // *w returns the wrapper
+     *                          // push_back() is a wrapper member function
+     *                          // that calls the corresponding view function
+     */
+    //@{
+    reducer_basic_string&       operator*()       { return *this; }
+    reducer_basic_string const& operator*() const { return *this; }
+
+    reducer_basic_string*       operator->()       { return this; }
+    reducer_basic_string const* operator->() const { return this; }
+    //@}
+
+    /** @name Upcast
+     *  @details In Cilk library 0.9, reducers were always cache-aligned. In
+     *  library  1.0, reducer cache alignment is optional. By default, reducers
+     *  are unaligned (i.e., just naturally aligned), but legacy wrappers
+     *  inherit from cache-aligned reducers for binary compatibility.
+     *
+     *  This means that a wrapper will automatically be upcast to its aligned
+     *  reducer base class. The following conversion operators provide
+     *  pseudo-upcasts to the corresponding unaligned reducer class.
+     */
+    //@{
+    operator reducer< op_basic_string<Char, Traits, Alloc, false> >& ()
+    {
+        return *reinterpret_cast< reducer< 
+            op_basic_string<Char, Traits, Alloc, false> >* 
+        >(this);
+    }
+    operator const reducer< op_basic_string<Char, Traits, Alloc, false> >& () const
+    {
+        return *reinterpret_cast< const reducer<
+            op_basic_string<Char, Traits, Alloc, false> >* 
+        >(this);
+    }
+    //@}
+};
+
+
+/** Convenience typedef for 8-bit strings
+ */
+typedef reducer_basic_string<char> reducer_string;
+
+/** Convenience typedef for 16-bit strings
+ */
+typedef reducer_basic_string<wchar_t> reducer_wstring;
+
+/// @cond internal
+
+/// @cond internal
+/** Metafunction specialization for reducer conversion.
+ *
+ *  This specialization of the @ref legacy_reducer_downcast template class 
+ *  defined in reducer.h causes the `reducer< op_basic_string<Char> >` class to
+ *  have an `operator reducer_basic_string<Char>& ()` conversion operator that
+ *  statically downcasts the `reducer<op_basic_string>` to the corresponding
+ *  `reducer_basic_string` type. (The reverse conversion, from 
+ *  `reducer_basic_string` to `reducer<op_basic_string>`, is just an upcast,
+ *  which is provided for free by the language.)
+ *
+ *  @ingroup ReducersString
+ */
+template<typename Char, typename Traits, typename Alloc, bool Align>
+struct legacy_reducer_downcast<
+    reducer<op_basic_string<Char, Traits, Alloc, Align> > >
+{
+    typedef reducer_basic_string<Char, Traits, Alloc> type;
+};
+
+/// @endcond
+
+//@}
+
+} // namespace cilk
+
+#endif //  REDUCER_STRING_H_INCLUDED
diff --git a/libcilkrts/include/cilktools/cilkscreen.h b/libcilkrts/include/cilktools/cilkscreen.h
new file mode 100644 (file)
index 0000000..c6986ae
--- /dev/null
@@ -0,0 +1,108 @@
+/* cilkscreen.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ * @copyright
+ * Copyright (C) 2010-2013, Intel Corporation
+ * All rights reserved.
+ * 
+ * @copyright
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * @copyright
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+#ifndef INCLUDED_CILKSCREEN_H
+#define INCLUDED_CILKSCREEN_H
+
+#include <cilk/cilk_api.h>
+
+/*
+ * Cilkscreen "functions".  These macros generate metadata in your application
+ * to notify Cilkscreen of program state changes
+ */
+
+#if ! defined(CILK_STUB) && defined(__INTEL_COMPILER)
+#  define __cilkscreen_metacall(annotation,expr) \
+    __notify_zc_intrinsic((char *)annotation, expr)
+#else
+#  define __cilkscreen_metacall(annotation,expr) ((void)annotation, (void)(expr))
+#endif
+
+/* Call once when a user thread enters a spawning function */
+#define __cilkscreen_enable_instrumentation() \
+    __cilkscreen_metacall("cilkscreen_enable_instrumentation", 0)
+
+/* Call once when a user thread exits a spawning function */
+#define  __cilkscreen_disable_instrumentation() \
+    __cilkscreen_metacall("cilkscreen_disable_instrumentation", 0)
+
+/* Call to temporarily disable cilkscreen instrumentation */
+#define __cilkscreen_enable_checking() \
+    __cilkscreen_metacall("cilkscreen_enable_checking", 0)
+
+/* Call to re-enable temporarily-disabled cilkscreen instrumentation */
+#define __cilkscreen_disable_checking() \
+    __cilkscreen_metacall("cilkscreen_disable_checking", 0)
+
+/* Inform cilkscreen that memory from begin to end can be reused without
+ * causing races (e.g., for memory that comes from a memory allocator) */
+#define __cilkscreen_clean(begin, end)                      \
+    do {                                                    \
+        void *__data[2] = { (begin), (end) };               \
+        __cilkscreen_metacall("cilkscreen_clean", &__data); \
+    } while(0)
+
+/* Inform cilkscreen that a lock is being acquired.
+ * If the lock type is not a handle, then the caller should take its address
+ * and pass the pointer to the lock.  Otherwise, the caller should pass the
+ * lock handle directly.
+ */
+#define __cilkscreen_acquire_lock(lock) \
+    __cilkscreen_metacall("cilkscreen_acquire_lock", (lock))
+
+#define __cilkscreen_release_lock(lock) \
+    __cilkscreen_metacall("cilkscreen_release_lock", (lock))
+
+/*
+ * Metacall data
+ *
+ * A metacall is a way to pass data to a function implemented by a tool.
+ * Metacalls are always instrumented when the tool is loaded.
+ */
+
+// Tool code for Cilkscreen
+#define METACALL_TOOL_CILKSCREEN 1
+
+// Metacall codes implemented by Cilkscreen
+#define CS_METACALL_PUTS 0  // Write string to the Cilkscreen log
+
+#define __cilkscreen_puts(text) \
+    __cilkrts_metacall(METACALL_TOOL_CILKSCREEN, CS_METACALL_PUTS, (void *)(const char *)text)
+
+#endif /* defined(INCLUDED_CILKSCREEN_H) */
diff --git a/libcilkrts/include/cilktools/cilkview.h b/libcilkrts/include/cilktools/cilkview.h
new file mode 100644 (file)
index 0000000..eb7d9d8
--- /dev/null
@@ -0,0 +1,278 @@
+/* cilkview.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ * @copyright
+ * Copyright (C) 2010-2013, Intel Corporation
+ * All rights reserved.
+ * 
+ * @copyright
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * @copyright
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+#ifndef INCLUDED_CILKVIEW_H
+#define INCLUDED_CILKVIEW_H
+
+#include <cilk/cilk_api.h>
+
+#ifdef _WIN32
+#   ifndef _WINBASE_
+__CILKRTS_BEGIN_EXTERN_C
+unsigned long __stdcall GetTickCount();
+__CILKRTS_END_EXTERN_C
+#   endif
+#endif  // _WIN32
+
+#if defined __unix__ || defined __APPLE__ || defined __VXWORKS__
+#   include <sys/time.h>
+#endif  // defined __unix__ || defined __APPLE__
+
+/// @brief Return the system clock with millisecond resolution
+///
+/// This function returns a long integer representing the number of
+/// milliseconds since an arbitrary starting point, e.g., since the system was
+/// started or since the Unix Epoch.  The result is meaningless by itself, but
+/// the difference between two sequential calls to __cilkview_getticks()
+/// represents the time interval that elapsed between them (in ms).
+static inline unsigned long long __cilkview_getticks()
+{
+#if __INTEL_COMPILER > 1200
+    // When inlined, prevent code motion around this call
+    __notify_zc_intrinsic((void*) "test_getticks_start", 0);
+#endif
+
+#ifdef _WIN32
+    // Return milliseconds elapsed since the system started
+    return GetTickCount();
+#elif defined(__unix__) || defined(__APPLE__) || defined __VXWORKS__
+    // Return milliseconds elapsed since the Unix Epoch
+    // (1-Jan-1970 00:00:00.000 UTC)
+    struct timeval t;
+    gettimeofday(&t, 0);
+    return t.tv_sec * 1000ULL + t.tv_usec / 1000;
+#else
+#   error test_getticks() not implemented for this OS
+#endif
+
+#if __INTEL_COMPILER > 1200
+    // When inlined, prevent code motion around this call
+    __notify_zc_intrinsic((void*) "test_getticks_end", 0);
+#endif
+}
+
+typedef struct
+{
+    unsigned int        size;           // Size of structure in bytes
+    unsigned int        status;         // 1 = success, 0 = failure
+    unsigned long long  time;           // Time in milliseconds
+    unsigned long long  work;
+    unsigned long long  span;
+    unsigned long long  burdened_span;
+    unsigned long long  spawns;
+    unsigned long long  syncs;
+    unsigned long long  strands;
+    unsigned long long  atomic_ins;
+    unsigned long long  frames;
+} cilkview_data_t;
+
+typedef struct
+{
+    cilkview_data_t *start;     // Values at start of interval
+    cilkview_data_t *end;       // Values at end of interval
+    const char *label;          // Name for this interval
+    unsigned int flags;         // What to do - see flags below
+} cilkview_report_t;
+
+// What __cilkview_report should do.  The flags can be ORed together
+enum
+{
+    CV_REPORT_WRITE_TO_LOG = 1,     // Write parallelism report to the log (xml or text)
+    CV_REPORT_WRITE_TO_RESULTS = 2  // Write parallelism data to results file
+};
+
+#ifndef CILKVIEW_NO_REPORT
+static void __cilkview_do_report(cilkview_data_t *start,
+                          cilkview_data_t *end,
+                          const char *label,
+                          unsigned int flags);
+#endif /* CILKVIEW_NO_REPORT */
+
+/*
+ * Metacall data
+ *
+ * A metacall is a way to pass data to a function implemented by a tool.
+ * Metacalls are always instrumented when the tool is loaded.
+ */
+
+// Tool code for Cilkview
+#define METACALL_TOOL_CILKVIEW 2
+
+// Metacall codes implemented by Cilkview
+enum
+{
+    CV_METACALL_PUTS,
+    CV_METACALL_QUERY,
+    CV_METACALL_START,
+    CV_METACALL_STOP,
+    CV_METACALL_RESET,
+    CV_METACALL_USE_DEFAULT_GRAIN,
+    CV_METACALL_CONNECTED,
+    CV_METACALL_SUSPEND,
+    CV_METACALL_RESUME,
+    CV_METACALL_REPORT
+};
+
+#if ! defined(CILK_STUB) && defined(__INTEL_COMPILER)
+#  define __cilkview_metacall(code,data) \
+    __cilkrts_metacall(METACALL_TOOL_CILKVIEW, code, data)
+#else
+#  define __cilkview_metacall(annotation,expr) (annotation, (void) (expr))
+#endif
+
+// Write arbitrary string to the log
+#define __cilkview_puts(arg) \
+    __cilkview_metacall(CV_METACALL_PUTS, arg)
+
+// Retrieve the Cilkview performance counters.  The parameter must be a 
+// cilkview_data_t
+#define __cilkview_query(d)                             \
+    do {                                                \
+        d.size = sizeof(d);                             \
+        d.status = 0;                                   \
+        __cilkview_metacall(CV_METACALL_QUERY, &d);     \
+        if (0 == d.status)                              \
+            d.time = __cilkview_getticks();             \
+    } while (0)
+
+// Write report to log or results file. If end is NULL, Cilkview will
+// use the current values.
+#define __cilkview_report(start, end, label, flags) \
+    __cilkview_do_report(start, end, label, flags)
+
+// Control the workspan performance counters for the final report
+#define __cilkview_workspan_start() \
+    __cilkview_metacall(CV_METACALL_START, 0)
+#define __cilkview_workspan_stop() \
+    __cilkview_metacall(CV_METACALL_STOP, 0)
+#define __cilkview_workspan_reset() \
+    __cilkview_metacall(CV_METACALL_RESET, 0)
+#define __cilkview_workspan_suspend() \
+    __cilkview_metacall(CV_METACALL_SUSPEND, 0)
+#define __cilkview_workspan_resume() \
+    __cilkview_metacall(CV_METACALL_RESUME, 0)
+
+#define __cilkview_use_default_grain_size() \
+    __cilkview_metacall(CV_METACALL_USE_DEFAULT, 0)
+
+// Sets the int is_connected to 1 if Cilkview is active
+#define __cilkview_connected(is_connected) \
+    __cilkview_metacall(CV_METACALL_CONNECTED, &is_connected)
+
+
+#ifndef CILKVIEW_NO_REPORT
+
+// Stop Microsoft include files from complaining about getenv and fopen
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef _WIN32
+#pragma warning(push)
+#pragma warning(disable: 1786) // Suppress warnings that getenv, fopen are deprecated
+#endif
+
+static void __cilkview_do_report(cilkview_data_t *start,
+                                 cilkview_data_t *end,
+                                 const char *label,
+                                 unsigned int flags)
+{
+    int under_cilkview = 0;
+    unsigned long long elapsed_ms;
+    int worker_count = 0;
+    char *nworkers;
+    char *outfile;
+    FILE *f;
+
+    // Check whether we're running under Cilkview
+    __cilkview_connected(under_cilkview);
+
+    // If we're running under Cilkview, let it do those things that need
+    // to be done
+    if (under_cilkview)
+    {
+        cilkview_report_t d = {start, end, label, flags};
+        __cilkview_metacall(CV_METACALL_REPORT, &d);
+        return;
+    }
+
+    // We're not running under Cilkview.
+    //
+    // If we weren't asked to write to the results file, we're done.
+    if (0 == (flags & CV_REPORT_WRITE_TO_RESULTS))
+        return;
+
+    // Calculate the elapse milliseconds
+    if (NULL == end)
+        elapsed_ms = __cilkview_getticks() - start->time;
+    else
+        elapsed_ms = end->time - start->time;
+
+    // Determine how many workers we're using for this trial run
+    nworkers = getenv("CILK_NWORKERS");
+    if (NULL != nworkers)
+        worker_count = atoi(nworkers);
+    if (0 == worker_count)
+        worker_count = 16;
+
+    // Open the output file and write the trial data to it
+    outfile = getenv("CILKVIEW_OUTFILE");
+    if (NULL == outfile)
+        outfile = (char *)"cilkview.out";
+
+    f = fopen(outfile, "a");
+    if (NULL == f)
+        fprintf(stderr, "__cilkview_do_report: unable to append to file %s\n", outfile);
+    else
+    {
+        fprintf(f, "%s trial %d %f\n", label,
+                worker_count,
+                ((float)elapsed_ms) / 1000.0f);
+        fclose(f);
+    }
+}
+#ifdef _WIN32
+#pragma warning(pop)
+#endif
+
+#endif  // CILKVIEW_NO_REPORT
+
+
+#endif /* ! defined(INCLUDED_CILKVIEW_H) */
diff --git a/libcilkrts/include/cilktools/fake_mutex.h b/libcilkrts/include/cilktools/fake_mutex.h
new file mode 100644 (file)
index 0000000..9ae0678
--- /dev/null
@@ -0,0 +1,92 @@
+/* fake_mutex.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ * @copyright
+ * Copyright (C) 2013, Intel Corporation
+ * All rights reserved.
+ * 
+ * @copyright
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * @copyright
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************
+ *
+ * Cilkscreen fake mutexes are provided to indicate to the Cilkscreen race
+ * detector that a race should be ignored.
+ *
+ * NOTE: This class does not provide mutual exclusion.  You should use the
+ * mutual exclusion constructs provided by TBB or your operating system to
+ * protect against real data races.
+ */
+
+#ifndef FAKE_MUTEX_H_INCLUDED
+#define FAKE_MUTEX_H_INCLUDED
+
+#include <cilktools/cilkscreen.h>
+
+namespace cilkscreen
+{
+    class fake_mutex
+    {
+    public:
+       fake_mutex() : locked(false)
+       {
+       }
+
+       ~fake_mutex()
+       {
+           __CILKRTS_ASSERT(! locked);
+       }
+
+        // Wait until mutex is available, then enter
+        void lock()
+        {
+            __cilkscreen_acquire_lock(&locked);
+           __CILKRTS_ASSERT(! locked);
+           locked = true;
+        }
+
+        // A fake mutex is always available
+        bool try_lock() { lock(); return true; }
+
+        // Releases the mutex
+        void unlock()
+        {
+           __CILKRTS_ASSERT(locked);
+           locked = false;
+            __cilkscreen_release_lock(&locked);
+        }
+
+    private:
+        bool locked;
+    };
+
+} // namespace cilk
+
+#endif  // FAKE_MUTEX_H_INCLUDED
diff --git a/libcilkrts/include/cilktools/lock_guard.h b/libcilkrts/include/cilktools/lock_guard.h
new file mode 100644 (file)
index 0000000..d513e2b
--- /dev/null
@@ -0,0 +1,86 @@
+/* lock_guard.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ * @copyright
+ * Copyright (C) 2011-2013, Intel Corporation
+ * All rights reserved.
+ * 
+ * @copyright
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * @copyright
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************
+ *
+ * Lock guard patterned after the std::lock_guard class template proposed in
+ * the C++ 0x draft standard.
+ *
+ * An object of type lock_guard controls the ownership of a mutex object
+ * within a scope. A lock_guard object maintains ownership of a mutex object
+ * throughout the lock_guard object's lifetime. The behavior of a program is
+ * undefined if the mutex referenced by pm does not exist for the entire
+ * lifetime of the lock_guard object.
+ */
+
+#ifndef LOCK_GUARD_H_INCLUDED
+#define LOCK_GUARD_H_INCLUDED
+
+#include <cilk/cilk.h>
+
+namespace cilkscreen
+{
+    template <class Mutex>
+    class lock_guard
+    {
+    public:
+        typedef Mutex mutex_type;
+
+        explicit lock_guard(mutex_type &m) : pm(m)
+        {
+            pm.lock();
+            locked = true;
+        }
+
+        ~lock_guard()
+        {
+            locked = false;
+            pm.unlock();
+        }
+
+    private:
+        lock_guard(lock_guard const&);
+        lock_guard& operator=(lock_guard const&);
+
+    private:
+        // exposition only:
+        mutex_type &pm;
+        bool locked;
+    };
+}
+
+#endif  // LOCK_GUARD_H_INCLUDED
diff --git a/libcilkrts/include/internal/abi.h b/libcilkrts/include/internal/abi.h
new file mode 100644 (file)
index 0000000..f45b5bc
--- /dev/null
@@ -0,0 +1,639 @@
+/*
+ *  abi.h
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************/
+
+/**
+ * @file abi.h
+ *
+ * @brief Defines the application binary interface between the compiler and
+ * the Intel Cilk Plus runtime.
+ */
+
+#ifndef CILK_INTERNAL_ABI_H
+#define CILK_INTERNAL_ABI_H
+
+
+#include <cilk/common.h>
+#include <stddef.h>  // Needed to define size_t
+
+/**
+ * Jump buffers are OS and architecture dependent
+ */
+#if ! defined(_MSC_VER)
+/* Non-Windows - only need 5 registers for the jump buffer for both IA32 and Intel64 */
+typedef void *__CILK_JUMP_BUFFER[5];
+
+/** OS-specific implementation of setjmp */
+#   define CILK_SETJMP(X) __builtin_setjmp(X)
+/** OS-specific implementation of longjmp */
+#   define CILK_LONGJMP(X) __builtin_longjmp(X,1)
+#else
+/* Windows - things are a little more complicated */
+#   if defined(_M_X64)
+/* Intel64 - Use an OS-defined jump buffer */
+#       include <setjmp.h>
+typedef jmp_buf __CILK_JUMP_BUFFER;
+
+#       define CILK_SETJMP(X) setjmp(X)
+#       define CILK_LONGJMP(X) longjmp(X, 1)
+#   elif defined(_M_IX86)
+/**
+ * Windows x86 - Use a simplified version of the Windows jump buffer for x86
+ * setjmp is provided by __cilkrts_setjmp which passes jump buffer in EAX and
+ * destination in EDX longjmp is provided by an internal routine which uses
+ * this structure
+ */
+typedef struct
+{
+    unsigned long Ebp;
+    unsigned long Ebx;
+    unsigned long Edi;
+    unsigned long Esi;
+    unsigned long Esp;
+    unsigned long Eip;
+    unsigned long Registration;
+    unsigned long TryLevel;
+} __CILK_JUMP_BUFFER;
+
+#    else
+#    error Unexpected architecture - Need to define __CILK_JUMP_BUFFER
+#    endif  /* _M_X64 */
+
+#endif  /* defined(_MSC_VER) */
+
+/* struct tags */
+typedef struct __cilkrts_stack_frame __cilkrts_stack_frame; ///< struct tag for stack frame
+
+// Forwarded declarations
+typedef struct global_state_t        global_state_t;  ///< Forwarded declaration for global state
+typedef struct local_state           local_state;     ///< Forwarded declaration for local state
+typedef struct cilkred_map           cilkred_map;     ///< Forward declaration for reducer map
+
+/// Forwarded declaration for system-dependent worker state
+typedef struct __cilkrts_worker_sysdep_state
+                                     __cilkrts_worker_sysdep_state;
+
+/**
+ * The worker struct contains per-worker information that needs to be
+ * visible to the compiler, or rooted here.
+ *
+ * For 32-bit Windows we need to be aligning the structures on 4-byte
+ * boundaries to match where ICL is allocating the birthrank and rank
+ * in the __cilkrts_stack_frame.  It's 4-byte aligned instead of 8-byte
+ * aligned.  This is OK because the compiler is dealing with the 64-bit
+ * quantities as two 32-bit values.  So change the packing to be on
+ * 4-byte boundaries.
+ *
+ * The fields of the worker struct can be classified as either local
+ * or shared.
+ *
+ *  Local: This field is only accessed by the thread bound to this
+ *    worker struct.  Local fields can be freely accessed without
+ *    acquiring locks.
+ *  
+ *  Shared: This field may be accessed by multiple worker threads.
+ *    Accesses to shared fields usually requires locks, except in
+ *    special situations where one can prove that locks are
+ *    unnecessary.
+ *
+ * The fields of the worker struct can also be classified as
+ * "read-only" if the field does not change after it is initialized.
+ * Otherwise, the field is "read/write".  Read-only fields do not
+ * require locks to access (ignoring the synchronization that might be
+ * needed for initialization if this can occur in parallel).
+ *
+ * Finally, we explicitly classify some fields as "synchronization"
+ * fields if they are used as part of a synchronization protocol in
+ * the runtime.  These variables are generally shared and read/write.
+ * Mostly, this category includes lock variables and other variables
+ * that are involved in synchronization protocols (i.e., the THE
+ * protocol).
+ */
+#if defined(_MSC_VER) && defined(_M_IX86)
+#pragma pack(push, 4)
+#endif
+
+struct __cilkrts_worker {
+    /**
+     * T, H, and E pointers in the THE protocol See "The implementation of
+     * the Cilk-5 multithreaded language", PLDI 1998:
+     * http://portal.acm.org/citation.cfm?doid=277652.277725
+     *
+     * Synchronization fields.  [shared read/write]
+     */
+    __cilkrts_stack_frame *volatile *volatile tail;
+    __cilkrts_stack_frame *volatile *volatile head;  /**< @copydoc tail */
+    __cilkrts_stack_frame *volatile *volatile exc;   /**< @copydoc tail */
+
+    /**
+     * Addition to the THE protocol to allow us to protect some set of
+     * entries in the tail queue from stealing.  Normally, this is set
+     * beyond the end of the task queue, indicating that all entries are
+     * available for stealing.  During exception handling, protected_tail
+     * may be set to the first entry in the task queue, indicating that
+     * stealing is not allowed.
+     *
+     * Synchronization field.
+     */
+    __cilkrts_stack_frame *volatile *volatile protected_tail;
+
+    /**
+     * Limit of the Lazy Task Queue, to detect queue overflow
+     * [local read-only]
+     */
+    __cilkrts_stack_frame *volatile *ltq_limit;
+
+    /**
+     * Worker id.
+     * [local read-only]
+     */
+    int32_t self;
+
+    /**
+     * Global state of the runtime system, opaque to the client.
+     * [local read-only]
+     */
+    global_state_t *g;
+
+    /**
+     * Additional per-worker state of the runtime system that we want
+     * to maintain hidden from the client.
+     * [shared read-only]
+     */
+    local_state *l;
+
+    /**
+     * Map from reducer names to reducer values.
+     * [local read/write]
+     */
+    cilkred_map *reducer_map;
+
+    /**
+     * A slot that points to the currently executing Cilk frame.
+     * [local read/write]
+     */
+    __cilkrts_stack_frame *current_stack_frame;
+
+    /**
+     * Reserved space for a pointer.
+     * Used to be __cilkrts_stack_frame *volatile *volatile saved_protected_tail; 
+     */
+    void* reserved;
+
+    /**
+     * System-dependent part of the worker state
+     * [local read-only]
+     */
+    __cilkrts_worker_sysdep_state *sysdep;
+
+#if __CILKRTS_ABI_VERSION >= 1
+    /**
+     * Per-worker pedigree information used to support scheduling-independent
+     * pseudo-random numbers.
+     * [local read/write]
+     */
+    __cilkrts_pedigree   pedigree;    
+#endif  /* __CILKRTS_ABI_VERSION >= 1 */
+};
+
+
+/**
+ * Every spawning function has a frame descriptor.  A spawning function
+ * is a function that spawns or detaches.  Only spawning functions
+ * are visible to the Cilk runtime.
+ */
+struct __cilkrts_stack_frame
+{
+    /**
+     * flags is an integer with values defined below.  Client code
+     * initializes flags to CILK_FRAME_VERSION before the first Cilk
+     * operation.
+     *
+     * The low 24-bits of the 'flags' field are the flags, proper.  The high
+     * 8-bits are the version number.
+     *
+     * IMPORTANT: bits in this word are set and read by the PARENT ONLY,
+     * not by a spawned child.  In particular, the STOLEN and UNSYNCHED
+     * bits are set on a steal and are read before a sync.  Since there
+     * is no synchronization (locking) on this word, any attempt to set
+     * or read these bits asynchronously in a child would result in a race.
+     */
+    uint32_t flags;
+
+    /** Not currently used.  Not initialized by Intel compiler. */
+    int32_t size;
+
+    /** 
+     * call_parent points to the __cilkrts_stack_frame of the closest
+     * ancestor spawning function, including spawn helpers, of this frame.
+     * It forms a linked list ending at the first stolen frame.
+     */
+    __cilkrts_stack_frame *call_parent;
+
+    /**
+     * The client copies the worker from TLS here when initializing
+     * the structure.  The runtime ensures that the field always points
+     * to the __cilkrts_worker which currently "owns" the frame.
+     */
+    __cilkrts_worker *worker;
+
+    /**
+     * Unix: Pending exception after sync.  The sync continuation
+     * must call __cilkrts_rethrow to handle the pending exception.
+     *
+     * Windows: the handler that _would_ have been registered if our
+     * handler were not there.  We maintain this for unwinding purposes.
+     * Win32: the value of this field is only defined in spawn helper
+     * functions
+     *
+     * Win64: except_data must be filled in  for all functions with a
+     * __cilkrts_stack_frame
+     */
+    void *except_data;
+
+    /**
+     * Before every spawn and nontrivial sync the client function
+     * saves its continuation here.
+     */
+    __CILK_JUMP_BUFFER ctx;
+
+#if __CILKRTS_ABI_VERSION >= 1
+    /**
+     * Architecture-specific floating point state.  mxcsr and fpcsr should be
+     * set when CILK_SETJMP is called in client code.  Note that the Win64
+     * jmpbuf for the Intel64 architecture already contains this information
+     * so there is no need to use these fields on that OS/architecture.
+     */
+    uint32_t mxcsr;
+    uint16_t fpcsr;         /**< @copydoc mxcsr */
+
+
+    /**
+     * reserved is not used at this time.  Client code should initialize it
+     * to 0 before the first Cilk operation
+     */
+    uint16_t reserved;
+
+    /**
+     * Pedigree information to support scheduling-independent pseudo-random
+     * numbers.  There are two views of this information.  The copy in a
+     * spawning function is used to stack the rank and communicate to the
+     * runtime on a steal or continuation.  The copy in a spawn helper is
+     * immutable once the function is detached and is a node in the pedigree.
+     * The union is used to make clear which view we're using.
+     *
+     * In the detach sequence Client code should:
+     *    - copy the worker pedigree into the spawn helper's pedigree
+     *    - copy the worker pedigree into the call parent's pedigree
+     *    - set the worker's rank to 0
+     *    - set the worker's pedigree.next to the spawn helper's pedigree
+     */
+    union
+    {
+        __cilkrts_pedigree spawn_helper_pedigree; /* Used in spawn helpers */
+        __cilkrts_pedigree parent_pedigree;       /* Used in spawning funcs */
+    };
+#endif  /* __CILKRTS_ABI_VERSION >= 1 */
+};
+
+/*
+ * Restore previous structure packing for 32-bit Windows
+ */
+#if defined(_MSC_VER) && defined(_M_IX86)
+#pragma pack(pop)
+#endif
+
+/* Values of the flags bitfield */
+/** CILK_FRAME_STOLEN is set if the frame has ever been stolen. */
+#define CILK_FRAME_STOLEN    0x01
+
+/**
+ * CILK_FRAME_UNSYNCHED is set if the frame has been stolen and
+ * is has not yet executed _Cilk_sync.  It is technically a misnomer in that a
+ * frame can have this flag set even if all children have returned.
+ */
+#define CILK_FRAME_UNSYNCHED 0x02
+
+/**
+ * Is this frame detached (spawned)?  If so the runtime needs
+ * to undo-detach in the slow path epilogue.
+ */
+#define CILK_FRAME_DETACHED  0x04
+
+/**
+ * CILK_FRAME_EXCEPTION_PROBED is set if the frame has been probed in the
+ * exception handler first pass
+ */
+#define CILK_FRAME_EXCEPTION_PROBED 0x08
+
+/** Is this frame receiving an exception after sync? */
+#define CILK_FRAME_EXCEPTING 0x10
+
+/**
+ * Is the pedigree unsynched?  That is, has a synch occurred that is not
+ * yet represented in the pedigree?
+ */
+#define CILK_FRAME_SF_PEDIGREE_UNSYNCHED 0x20
+
+/** Is this the last (oldest) Cilk frame? */
+#define CILK_FRAME_LAST             0x80
+
+/**
+ * Is this frame in the epilogue, or more generally after the last
+ * sync when it can no longer do any Cilk operations?
+ */
+#define CILK_FRAME_EXITING   0x0100
+
+/** Is this frame suspended? (used for debugging) */
+#define CILK_FRAME_SUSPENDED 0x8000
+
+/** Used by Windows exception handling to indicate that __cilkrts_leave_frame should do nothing */
+#define CILK_FRAME_UNWINDING 0x10000
+
+/*
+ * The low 24-bits of the 'flags' field are the flags, proper.  The high 8-bits
+ * are the version number.
+ */
+
+/** ABI version left shifted to the high byte */
+#define CILK_FRAME_VERSION (__CILKRTS_ABI_VERSION << 24)
+
+/** Mask for the flags field to isolate the version bits */
+#define CILK_FRAME_VERSION_MASK  0xFF000000
+
+/** Mask for the flags field to isolate the flag bits */
+#define CILK_FRAME_FLAGS_MASK    0x00FFFFFF
+
+/** Convenience macro to provide access the version portion of the flags field */
+#define CILK_FRAME_VERSION_VALUE(_flags) (((_flags) & CILK_FRAME_VERSION_MASK) >> 24)
+
+/** Any undefined bits are reserved and must be zero ("MBZ" = "Must Be Zero") */
+#define CILK_FRAME_MBZ  (~ (CILK_FRAME_STOLEN | \
+                            CILK_FRAME_UNSYNCHED | \
+                            CILK_FRAME_DETACHED | \
+                            CILK_FRAME_EXCEPTION_PROBED | \
+                            CILK_FRAME_EXCEPTING | \
+                            CILK_FRAME_SF_PEDIGREE_UNSYNCHED | \
+                            CILK_FRAME_LAST | \
+                            CILK_FRAME_EXITING | \
+                            CILK_FRAME_SUSPENDED | \
+                            CILK_FRAME_UNWINDING | \
+                            CILK_FRAME_VERSION_MASK))
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * Call __cilkrts_enter_frame to initialize an ABI 0 frame descriptor.
+ * Initialize the frame descriptor before spawn or detach.  A function that
+ * conditionally does Cilk operations need not initialize the frame descriptor
+ * in a code path that never uses it.
+ *
+ * @param sf The __cilkrts_stack_frame that is to be initialized.
+ */
+CILK_ABI(void) __cilkrts_enter_frame(__cilkrts_stack_frame* sf);
+
+/**
+ * Call __cilkrts_enter_frame to initialize an ABI 1 frame descriptor.
+ * Initialize the frame descriptor before spawn or detach.  A function that
+ * conditionally does Cilk operations need not initialize the frame descriptor
+ * in a code path that never uses it.
+ *
+ * @param sf The __cilkrts_stack_frame that is to be initialized.
+ */
+CILK_ABI(void) __cilkrts_enter_frame_1(__cilkrts_stack_frame* sf);
+
+/**
+ * __cilkrts_enter_frame_fast is the same as __cilkrts_enter_frame, except it
+ * assumes that the thread has already been bound to a worker.
+ *
+ * @param sf The __cilkrts_stack_frame that is to be initialized.
+ */
+CILK_ABI(void) __cilkrts_enter_frame_fast(__cilkrts_stack_frame *sf);
+
+/**
+ * __cilkrts_enter_frame_fast_1 is the same as __cilkrts_enter_frame_1,
+ * except it assumes that the thread has already been bound to a worker.
+ *
+ * @param sf The __cilkrts_stack_frame that is to be initialized.
+ */
+CILK_ABI(void) __cilkrts_enter_frame_fast_1(__cilkrts_stack_frame *sf);
+
+/**
+ * Call leave_frame before leaving a frame, after sync.  This function
+ * returns except in a spawn wrapper where the parent has been stolen.
+ *
+ * @param sf The __cilkrts_stack_frame that is to be left.
+ */
+CILK_ABI(void) __cilkrts_leave_frame(__cilkrts_stack_frame *sf);
+
+/**
+ * Wait for any spawned children of this function to complete before
+ * continuing.  This function will only return when the join counter
+ * has gone to 0.  Other workers will re-enter the scheduling loop to
+ * attempt to steal additional work.
+ *
+ * @param sf The __cilkrts_stack_frame that is to be synched.
+ */
+CILK_ABI(void) __cilkrts_sync(__cilkrts_stack_frame *sf);
+
+/**
+ * Called when an exception is escaping a spawn * wrapper.
+ * The stack frame's except_data field is the C++ runtime
+ * exception object.  If NULL (temporary workaround) the
+ * currently caught exception should be rethrown.  If this
+ * function returns normal exit functions must be called;
+ * undo-detach will have been done.
+ *
+ * @param sf The __cilkrts_stack_frame for the function that
+ * is raising an exception.
+ */
+CILK_ABI_THROWS(void)
+    __cilkrts_return_exception(__cilkrts_stack_frame *sf);
+
+/**
+ * Called to re-raise an exception.
+ *
+ * @param sf The __cilkrts_stack_frame for the function that
+ * is raising an exception.
+ */
+CILK_ABI_THROWS(void) __cilkrts_rethrow(__cilkrts_stack_frame *sf);
+
+/**
+ * Called at the beginning of a spawning function to get the worker
+ * that this function is running on.  This worker will be used to
+ * initialize the __cilkrts_stack_frame.
+ *
+ * @return The __cilkrts_worker that the function is running on.
+ * @return NULL if this thread is not yet bound to a worker.
+ */
+CILK_ABI(__cilkrts_worker_ptr) __cilkrts_get_tls_worker(void);
+
+/**
+ * Similar to __cilkrts_get_tls_worker, but assumes that TLS has been
+ * initialized.
+ *
+ * @return The __cilkrts_worker that the function is running on.
+ * @return NULL if this thread is not yet bound to a worker.
+ */
+CILK_ABI(__cilkrts_worker_ptr) __cilkrts_get_tls_worker_fast(void);
+
+/**
+ * Binds a thread to the runtime by associating a __cilkrts_worker with
+ * it.  Called if __cilkrts_get_tls_worker returns NULL.  This function will
+ * initialize the runtime the first time it is called.
+ *
+ * This function is versioned by the ABI version number.  The runtime
+ * will export all previous versions.  This prevents using an application
+ * built with a newer compiler against an old runtime.
+ *
+ * @return The __cilkrts_worker bound to the thread the function is running
+ * on.
+ */
+CILK_ABI(__cilkrts_worker_ptr) __cilkrts_bind_thread_1(void);
+
+typedef uint32_t cilk32_t;  /**< 32-bit unsigned type for cilk_for loop indicies */
+
+typedef uint64_t cilk64_t;  /**< 64-bit unsigned type for cilk_for loop indicies */
+
+/**
+ * Signature for the lambda function generated for the body of a cilk_for loop
+ * which uses 32-bit indicies
+ */
+typedef void (*__cilk_abi_f32_t)(void *data, cilk32_t low, cilk32_t high);
+
+/**
+ * Signature for the lambda function generated for the body of a cilk_for lop
+ * which uses 64-bit indicies
+ */
+typedef void (*__cilk_abi_f64_t)(void *data, cilk64_t low, cilk64_t high);
+
+/**
+ * @brief cilk_for implementation for 32-bit indexes.
+ *
+ * @param body The lambda function for the body of the cilk_for.  The lambda
+ * function will be called to execute each grain of work.
+ * @param data Data passed by the compiler into the lambda function.  Provides
+ * access to data outside the cilk_for body.
+ * @param count Number of steps in the loop.
+ * @param grain This parameter allows the compiler to pass a value from a
+ * \#pragam(grainsize) statement to allow the user to control the grainsize.  If
+ * there isn't a \#pragma(grainsize) immediately preceeding cilk_for loop, Pass
+ * 0 to specify that the runtime should calculate the grainsize using its own
+ * hueristicts.
+ */
+CILK_ABI_THROWS(void) __cilkrts_cilk_for_32(__cilk_abi_f32_t body,
+                                            void *data,
+                                            cilk32_t count,
+                                            int grain);
+
+/**
+ * @brief cilk_for implementation for 64-bit indexes.
+ *
+ * @copydetails __cilkrts_cilk_for_32
+ */
+CILK_ABI_THROWS(void) __cilkrts_cilk_for_64(__cilk_abi_f64_t body,
+                                            void *data,
+                                            cilk64_t count,
+                                            int grain);
+
+/**
+ * @brief Allocate memory for variable length arrays. If the frame is
+ * sync'd, the memory will be allocated on the stack, otherwise it will
+ * be allocated from the heap.
+ *
+ * @param sf The __cilkrts_stack_frame for the function allocating the
+ * memory.
+ * @param size The number of bytes requested.
+ * @param distance_from_sp_to_alloca_area ?.
+ * @param align Alignment required.  Always >= minimum stack alignment,
+ * >= ptr_size, and always a power of 2.
+ * @param needs_tag Non-zero if the pointer being returned needs to be
+ * tagged
+ *
+ * @return The address of the memory block allocated.
+ */
+
+CILK_ABI(__cilkrts_void_ptr)
+__cilkrts_stack_alloc(__cilkrts_stack_frame *sf,
+                      size_t size,
+                      size_t distance_from_sp_to_alloca_area,
+                      uint32_t align,
+                      uint32_t needs_tag);
+
+/**
+ * @brief Free memory allocated by _cilkrts_stack_alloc() for variable length
+ * arrays.
+ *
+ * @param sf The __cilkrts_stack_frame for the function allocating the
+ * memory.
+ * @param p Pointer to the memory block to be freed.
+ * @param size The number of bytes requested.
+ * @param distance_from_sp_to_alloca_area ?.
+ * @param align Alignment required.  Always >= minimum stack alignment,
+ * >= ptr_size, and always a power of 2.
+ * @param know_from_stack Non-zero if the pointer is known to have been
+ * allocated on the stack and has no tag.
+ */
+CILK_ABI(void)
+__cilkrts_stack_free(__cilkrts_stack_frame *sf,
+                     void *p,
+                     size_t size,
+                     size_t distance_from_sp_to_alloca_area,
+                     uint32_t align,
+                     uint32_t known_from_stack);
+
+/**
+ * @brief System-dependent code to save floating point control information
+ * to an ABI 1 or higher @c __cilkrts_stack_frame.  If possible (and necessary)
+ * the code to save the floating point control information should be inlined.
+ *
+ * Note that this function does *not* save the current floating point
+ * registers.  It saves the floating point control words that control
+ * precision and rounding and stuff like that.
+ *
+ * This function will be a noop for architectures that don't have warts
+ * like the floating point control words, or where the information is
+ * already being saved by the setjmp.
+ *
+ * @param sf  @c __cilkrts_stack_frame for the frame we're saving the
+ * floating point control information in.
+ */
+CILK_ABI(void)
+__cilkrts_save_fp_ctrl_state(__cilkrts_stack_frame *sf);
+
+__CILKRTS_END_EXTERN_C
+#endif /* include guard */
diff --git a/libcilkrts/include/internal/cilk_fake.h b/libcilkrts/include/internal/cilk_fake.h
new file mode 100644 (file)
index 0000000..2386dd6
--- /dev/null
@@ -0,0 +1,477 @@
+/* cilk_fake.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2011-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file cilk_fake.h
+ *
+ * @brief Macros to simulate a compiled Cilk program.
+ *
+ * Used carefully, these macros can be used to create a Cilk program with a
+ * non-Cilk compiler by manually inserting the code necessary for interacting
+ * with the Cilk runtime library.  They are not intended to be pretty (you
+ * wouldn't want to write a whole program using these macros), but they are
+ * useful for experiments.  They also work well as an illustration of what the
+ * compiler generates.
+ *
+ * Details of the mechanisms used in these macros are described in
+ * design-notes/CilkPlusABI.docx
+ *
+ * Example 1: fib in C++
+ * ---------------------
+ *
+ *  #include <internal/cilk_fake.h>
+ *  
+ *  int fib(int n)
+ *  {
+ *      CILK_FAKE_PROLOG();
+ *  
+ *      if (n < 2)
+ *          return n;
+ *  
+ *      int a, b;
+ *      CILK_FAKE_SPAWN_R(a, fib(n - 1));
+ *      b = fib(n - 2);
+ *      CILK_FAKE_SYNC();
+ *  
+ *      return a + b;
+ *  }
+ *  
+ *
+ * Example 2: fib in C
+ * -------------------
+ *
+ *  #include <internal/cilk_fake.h>
+ *  
+ *  int fib(int n);
+ *  
+ *  void fib_spawn_helper(__cilkrts_stack_frame* parent_sf, int* a, int n)
+ *  {
+ *      CILK_FAKE_SPAWN_HELPER_PROLOG(*parent_sf);
+ *      *a = fib(n - 1);
+ *      CILK_FAKE_SPAWN_HELPER_EPILOG();
+ *  }
+ *  
+ *  int fib(int n)
+ *  {
+ *      CILK_FAKE_PROLOG();
+ *  
+ *      if (n < 2)
+ *          return n;
+ *  
+ *      int a, b;
+ *      CILK_FAKE_CALL_SPAWN_HELPER(fib_spawn_helper(&__cilk_sf, &a, n));
+ *      b = fib(n - 2);
+ *      CILK_FAKE_SYNC();
+ *  
+ *      CILK_FAKE_EPILOG();
+ *      return a + b;
+ *  }
+ */
+
+#ifndef INCLUDED_CILK_FAKE_DOT_H
+#define INCLUDED_CILK_FAKE_DOT_H
+
+// This header implements ABI version 1.  If __CILKRTS_ABI_VERSION is already
+// defined but is less than 1, then the data structures in <internal/abi.h>
+// will not match the expectations of facilities in this header.  Therefore,
+// for successful compilation, __CILKRTS_ABI_VERSION must either be not
+// defined, or defined to be 1 or greater.
+#ifndef __CILKRTS_ABI_VERSION
+    // ABI version was not specified.  Set it to 1.
+#   define __CILKRTS_ABI_VERSION 1
+#elif __CILKRTS_ABI_VERSION < 1
+    // ABI version was specified but was too old.  Fail compilation.
+#   error cilk_fake.h requirs an ABI version of 1 or greater
+#endif
+
+#include <internal/abi.h>
+
+// alloca is defined in malloc.h on Windows, alloca.h on Linux
+#ifndef _MSC_VER
+#include <alloca.h>
+#else
+#include <malloc.h>
+// Define offsetof
+#include <stddef.h>
+#endif
+
+// Allows use of a different version that the one defined in abi.h
+#define CILK_FAKE_VERSION_FLAG (__CILKRTS_ABI_VERSION << 24)
+    
+/* Initialize frame. To be called when worker is known */
+__CILKRTS_INLINE void __cilk_fake_enter_frame_fast(__cilkrts_stack_frame *sf,
+                                                   __cilkrts_worker      *w)
+{
+    sf->call_parent = w->current_stack_frame;
+    sf->worker      = w;
+    sf->flags       = CILK_FAKE_VERSION_FLAG;
+    w->current_stack_frame = sf;
+}
+
+/* Initialize frame. To be called when worker is not known */
+__CILKRTS_INLINE void __cilk_fake_enter_frame(__cilkrts_stack_frame *sf)
+{
+    __cilkrts_worker* w = __cilkrts_get_tls_worker();
+    uint32_t          last_flag = 0;
+    if (! w) {
+        w = __cilkrts_bind_thread_1();
+        last_flag = CILK_FRAME_LAST;
+    }
+    __cilk_fake_enter_frame_fast(sf, w);
+    sf->flags |= last_flag;
+}
+
+/* Initialize frame. To be called within the spawn helper */
+__CILKRTS_INLINE void __cilk_fake_helper_enter_frame(
+    __cilkrts_stack_frame *sf,
+    __cilkrts_stack_frame *parent_sf)
+{
+    sf->worker      = 0;
+    sf->call_parent = parent_sf;
+}
+
+/* Called from the spawn helper to push the parent continuation on the task
+ * deque so that it can be stolen.
+ */
+__CILKRTS_INLINE void __cilk_fake_detach(__cilkrts_stack_frame *sf)
+{
+    /* Initialize spawn helper frame.
+     * call_parent was saved in __cilk_fake_helper_enter_frame */
+    __cilkrts_stack_frame *parent = sf->call_parent;
+    __cilkrts_worker *w = parent->worker;
+    __cilk_fake_enter_frame_fast(sf, w);
+
+    /* Append a node to the pedigree */
+    sf->spawn_helper_pedigree = w->pedigree;
+    parent->parent_pedigree = w->pedigree;
+    w->pedigree.rank = 0;
+    w->pedigree.parent = &sf->spawn_helper_pedigree;
+
+    /* Push parent onto the task deque */
+    __cilkrts_stack_frame *volatile *tail = w->tail;
+    *tail++ = sf->call_parent;
+    /* The stores must be separated by a store fence (noop on x86)
+     * or the second store is a release (st8.rel on Itanium)   */
+    w->tail = tail;
+    sf->flags |= CILK_FRAME_DETACHED;
+}
+
+/* This variable is used in CILK_FAKE_FORCE_FRAME_PTR(), below */
+static int __cilk_fake_dummy = 8;
+
+/* The following macro is used to force the compiler into generating a frame
+ * pointer.  We never change the value of __cilk_fake_dummy, so the alloca()
+ * is never called, but we need the 'if' statement and the __cilk_fake_dummy
+ * variable so that the compiler does not attempt to optimize it away.
+ */
+#define CILK_FAKE_FORCE_FRAME_PTR(sf) do {                              \
+    if (__builtin_expect(1 & __cilk_fake_dummy, 0))                     \
+        (sf).worker = (__cilkrts_worker*) alloca(__cilk_fake_dummy);    \
+} while (0)
+
+#ifndef CILK_FAKE_NO_SHRINKWRAP
+    /* "shrink-wrap" optimization enabled.  Do not initialize frame on entry,
+     * except to clear worker pointer.  Instead, defer initialization until
+     * the first spawn.
+     */
+#   define CILK_FAKE_INITIAL_ENTER_FRAME(sf) ((void) ((sf).worker = 0))
+#   define CILK_FAKE_DEFERRED_ENTER_FRAME(sf) do {            \
+        if (! (sf).worker) __cilk_fake_enter_frame(&(sf));    \
+    } while (0)
+#else
+    /* "shrink-wrap" optimization disabled.  Initialize frame immediately on
+     * entry.  Do not initialize frame on spawn.
+     */
+#   define CILK_FAKE_INITIAL_ENTER_FRAME(sf) \
+        __cilk_fake_enter_frame(&(sf))
+#   define CILK_FAKE_DEFERRED_ENTER_FRAME(sf) ((void) &(sf))
+#endif
+
+/* Prologue of a spawning function.  Declares and initializes the stack
+ * frame.
+ */
+#define CILK_FAKE_PROLOG()                                           \
+    __cilk_fake_stack_frame __cilk_sf;                               \
+    CILK_FAKE_FORCE_FRAME_PTR(__cilk_sf);                            \
+    CILK_FAKE_INITIAL_ENTER_FRAME(__cilk_sf)
+
+/* Prologue of a spawning function where the current worker is already known.
+ * Declares and initializes the stack frame without looking up the worker from
+ * TLS.
+ */
+#define CILK_FAKE_PROLOG_FAST(w)                                     \
+    __cilk_fake_stack_frame __cilk_sf;                               \
+    CILK_FAKE_FORCE_FRAME_PTR(__cilk_sf);                            \
+    __cilk_fake_enter_frame_fast(&__cilk_sf, (w))
+
+/* Simulate a cilk_sync */
+#define CILK_FAKE_SYNC() CILK_FAKE_SYNC_IMP(__cilk_sf)
+
+/* Epilog at the end of a spawning function.  Does a sync and calls the
+ * runtime for leaving the frame.
+ */
+#ifdef __cplusplus
+    // Epilogue is run automatically by __cilk_fake_stack_frame destructor.
+#   define CILK_FAKE_EPILOG() ((void) __cilk_sf)
+#else
+#   define CILK_FAKE_EPILOG() CILK_FAKE_CLEANUP_FRAME(__cilk_sf)
+#endif // C
+
+/* Implementation of spawning function epilog.  See CILK_FAKE_EPILOG macro and
+ * __cilk_fake_stack_frame destructor body.
+ */
+#define CILK_FAKE_CLEANUP_FRAME(sf) do {                     \
+    if (! (sf).worker) break;                                \
+    CILK_FAKE_SYNC_IMP(sf);                                  \
+    CILK_FAKE_POP_FRAME(sf);                                 \
+    if ((sf).flags != CILK_FAKE_VERSION_FLAG)                \
+        __cilkrts_leave_frame(&(sf));                        \
+} while (0)
+
+/* Implementation of CILK_FAKE_SYNC with sf argument */
+#define CILK_FAKE_SYNC_IMP(sf) do {                                       \
+    if (__builtin_expect((sf).flags & CILK_FRAME_UNSYNCHED, 0))      {    \
+        (sf).parent_pedigree = (sf).worker->pedigree;                     \
+        CILK_FAKE_SAVE_FP(sf);                                            \
+        if (! CILK_SETJMP((sf).ctx))                                      \
+            __cilkrts_sync(&(sf));                                        \
+    }                                                                     \
+    ++(sf).worker->pedigree.rank;                                         \
+} while (0)
+
+/* Save the floating-point control registers.
+ * The definition of CILK_FAKE_SAVE_FP is compiler specific (and
+ * architecture specific on Windows)
+ */
+#ifdef _MSC_VER
+#   define MXCSR_OFFSET offsetof(struct __cilkrts_stack_frame, mxcsr)
+#   define FPCSR_OFFSET offsetof(struct __cilkrts_stack_frame, fpcsr)
+#   if defined(_M_IX86)
+/* Windows x86 */
+#       define CILK_FAKE_SAVE_FP(sf) do {                               \
+            __asm                                                       \
+            {                                                           \
+                mov eax, sf                                             \
+                stmxcsr [eax+MXCSR_OFFSET]                              \
+                fnstcw  [eax+FPCSR_OFFSET]                              \
+            }                                                           \
+        } while (0)
+#   elif defined(_M_X64)
+/* Windows Intel64 - Not needed - saved by setjmp call */
+#       define CILK_FAKE_SAVE_FP(sf) ((void) sf)
+#   else
+#       error "Unknown architecture"
+#   endif /* Microsoft architecture specifics */
+#else
+/* Non-Windows */
+#   define CILK_FAKE_SAVE_FP(sf) do {                                   \
+        __asm__ ( "stmxcsr %0\n\t"                                      \
+                  "fnstcw %1" : : "m" ((sf).mxcsr), "m" ((sf).fpcsr));  \
+    } while (0)
+#endif
+
+/* Call the spawn helper as part of a fake spawn */
+#define CILK_FAKE_CALL_SPAWN_HELPER(helper) do {                    \
+    CILK_FAKE_DEFERRED_ENTER_FRAME(__cilk_sf);                      \
+    CILK_FAKE_SAVE_FP(__cilk_sf);                                   \
+    if (__builtin_expect(! CILK_SETJMP(__cilk_sf.ctx), 1)) {        \
+        helper;                                                     \
+    }                                                               \
+} while (0)
+
+/* Body of a spawn helper function.  In addition to the worker and the
+ * expression to spawn, pass it any number of statements to be executed before
+ * detaching.
+ */
+#define CILK_FAKE_SPAWN_HELPER_BODY(parent_sf, expr, ...)                   \
+    CILK_FAKE_SPAWN_HELPER_PROLOG(parent_sf);                               \
+    __VA_ARGS__;                                                            \
+    __cilk_fake_detach(&__cilk_sf);                                         \
+    expr;                                                                   \
+    CILK_FAKE_SPAWN_HELPER_EPILOG()
+
+/* Prolog for a spawn helper function */
+#define CILK_FAKE_SPAWN_HELPER_PROLOG(parent_sf)                     \
+    __cilk_fake_spawn_helper_stack_frame __cilk_sf;                  \
+    __cilk_fake_helper_enter_frame(&__cilk_sf, &(parent_sf))
+
+/* Implementation of spawn helper epilog.  See CILK_FAKE_SPAWN_HELPER_EPILOG
+ * and the __cilk_fake_spawn_helper_frame destructor.
+ */
+#define CILK_FAKE_SPAWN_HELPER_CLEANUP_FRAME(sf) do {                \
+    if (! (sf).worker) break;                                        \
+    CILK_FAKE_POP_FRAME(sf);                                         \
+    __cilkrts_leave_frame(&(sf));                                    \
+} while (0)
+
+/* Epilog to execute at the end of a spawn helper */
+#ifdef __cplusplus
+    // Epilog handled by __cilk_fake_spawn_helper_stack_frame destructor
+#   define CILK_FAKE_SPAWN_HELPER_EPILOG() ((void) __cilk_sf)
+#else
+#   define CILK_FAKE_SPAWN_HELPER_EPILOG() \
+        CILK_FAKE_SPAWN_HELPER_CLEANUP_FRAME(__cilk_sf)
+#endif
+
+/* Pop the current frame off of the call chain */
+#define CILK_FAKE_POP_FRAME(sf) do {                       \
+    (sf).worker->current_stack_frame = (sf).call_parent;   \
+    (sf).call_parent = 0;                                  \
+} while (0)
+
+#ifdef _WIN32
+/* define macros for synching functions before allowing them to propagate. */
+#   define CILK_FAKE_EXCEPT_BEGIN                              \
+    if (0 == CILK_SETJMP(__cilk_sf.except_ctx)) {
+
+#   define CILK_FAKE_EXCEPT_END                                               \
+    } else {                                                                  \
+        assert((__cilk_sf.flags & (CILK_FRAME_UNSYNCHED|CILK_FRAME_EXCEPTING))\
+                == CILK_FRAME_EXCEPTING);                                     \
+        __cilkrts_rethrow(&__cilk_sf);                                        \
+        exit(0);                                                              \
+    }
+#else
+#   define CILK_EXCEPT_BEGIN {
+#   define CILK_EXCEPT_END   }
+#endif
+
+#ifdef __cplusplus
+// The following definitions depend on C++ features.
+
+// Wrap a functor (probably a lambda), so that a call to it cannot be
+// inlined.
+template <typename F>
+class __cilk_fake_noinline_wrapper
+{
+    F&& m_fn;
+public:
+    __cilk_fake_noinline_wrapper(F&& fn) : m_fn(static_cast<F&&>(fn)) { }
+
+#ifdef _WIN32
+    __declspec(noinline) void operator()(__cilkrts_stack_frame *sf);
+#else
+    void operator()(__cilkrts_stack_frame *sf) __attribute__((noinline));
+#endif
+
+};
+
+template <typename F>
+void __cilk_fake_noinline_wrapper<F>::operator()(__cilkrts_stack_frame *sf)
+{
+    m_fn(sf);
+}
+
+template <typename F>
+inline
+__cilk_fake_noinline_wrapper<F> __cilk_fake_make_noinline_wrapper(F&& fn)
+{
+    return __cilk_fake_noinline_wrapper<F>(static_cast<F&&>(fn));
+}
+
+// Simulate "_Cilk_spawn expr", where expr must be a function call.
+//
+// Note: this macro does not correctly construct function arguments.
+// According to the ABI specification, function arguments should be evaluated
+// before the detach and destroyed after the detach.  This macro both
+// evaluates and destroys them after the detach.  This means that if any part
+// of the function argument expression depends on a value that is modified in
+// the continuation of the spawn, race will occur between the continuation and
+// the argument evaluation.
+//
+// To work around this problem, this macro accepts an arbitrary list of
+// declarations and statements (separated by semicolons) that are evaluated
+// before the detach.  Thus, to simulate:
+//
+//    _Cilk_spawn f(expr);
+//
+// one would write:
+//
+//    CILK_FAKE_SPAWN(f(arg), auto arg = expr);
+//
+// Despite appearing in the reverse order, the 'arg' variable is created and
+// initialized before the detach and the call to f(arg) occurs after the
+// detach.
+#define CILK_FAKE_SPAWN(expr, ...)                                  \
+    CILK_FAKE_CALL_SPAWN_HELPER(                                    \
+        CILK_FAKE_SPAWN_HELPER(expr, __VA_ARGS__)(&__cilk_sf))
+
+// Simulate "ret = cilk_spawn expr".  See CILK_FAKE_SPAWN for constraints.
+#define CILK_FAKE_SPAWN_R(ret, expr, ...) \
+    CILK_FAKE_SPAWN(((ret) = (expr)), __VA_ARGS__)
+
+// Create a spawn helper as a C++11 lambda function.  In addition to the
+// expression to spawn, this macro takes a any number of statements to be
+// executed before detaching.
+#define CILK_FAKE_SPAWN_HELPER(expr, ...)                                     \
+    __cilk_fake_make_noinline_wrapper([&](__cilkrts_stack_frame *parent_sf) { \
+        CILK_FAKE_SPAWN_HELPER_BODY(*parent_sf, expr, __VA_ARGS__);           \
+    })
+
+// C++ version of a __cilkrts_stack_frame for a spawning function.
+// This struct is identical to __cilkrts_stack_frame except that the
+// destructor automatically does frame cleanup.
+struct __cilk_fake_stack_frame : __cilkrts_stack_frame
+{
+    // Extension of __cilkrts_stack_frame with constructor and destructor
+    __cilk_fake_stack_frame() { }
+    __forceinline ~__cilk_fake_stack_frame() {
+        CILK_FAKE_CLEANUP_FRAME(*this);
+    }
+};
+
+// C++ version of a __cilkrts_stack_frame for a spawn helper.
+// This struct is identical to __cilkrts_stack_frame except that the
+// destructor automatically does frame cleanup.
+struct __cilk_fake_spawn_helper_stack_frame : __cilkrts_stack_frame
+{
+    // Extension of __cilkrts_stack_frame with constructor and destructor
+    __cilk_fake_spawn_helper_stack_frame() { worker = 0; }
+    __forceinline ~__cilk_fake_spawn_helper_stack_frame() {
+        CILK_FAKE_SPAWN_HELPER_CLEANUP_FRAME(*this);            
+    }
+};
+#else
+// For C, __cilk_fake_stack_frame and __cilk_fake_spawn_helper_stack_frame are
+// identical to __cilkrts_stack_frame.  Frame cleanup must be performed
+// excplicitly (in CILK_FAKE_EPILOG and CILK_FAKE_SPAWN_HELPER_EPILOG)
+typedef __cilkrts_stack_frame __cilk_fake_stack_frame;
+typedef __cilkrts_stack_frame __cilk_fake_spawn_helper_stack_frame;
+#endif
+
+#endif // ! defined(INCLUDED_CILK_FAKE_DOT_H)
diff --git a/libcilkrts/include/internal/cilk_version.h b/libcilkrts/include/internal/cilk_version.h
new file mode 100644 (file)
index 0000000..f628338
--- /dev/null
@@ -0,0 +1,47 @@
+// cilk_version.h
+//
+//  @copyright
+//  Copyright (C) 2009-2013, Intel Corporation
+//  All rights reserved.
+//  
+//  @copyright
+//  Redistribution and use in source and binary forms, with or without
+//  modification, are permitted provided that the following conditions
+//  are met:
+//  
+//    * Redistributions of source code must retain the above copyright
+//      notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in
+//      the documentation and/or other materials provided with the
+//      distribution.
+//    * Neither the name of Intel Corporation nor the names of its
+//      contributors may be used to endorse or promote products derived
+//      from this software without specific prior written permission.
+//  
+//  @copyright
+//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+//  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+//  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+//  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+//  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+//  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+//  POSSIBILITY OF SUCH DAMAGE.
+// DO NOT EDIT THIS FILE!
+//
+// It was automatically generated by cilkrts/include/internal/Makefile
+
+#define VERSION_MAJOR 2
+#define VERSION_MINOR 0
+#define VERSION_BUILD 3902
+#define VERSION_REV 0
+#define VERSION_STRING "2,0,3902,0"
+#define VERSION_HASH "b4e38f4f7e3e"
+#define VERSION_BRANCH "v14.0"
+#define TBB_REV_NUMBER ""
+#define VERSION_YEAR "2013"
diff --git a/libcilkrts/include/internal/metacall.h b/libcilkrts/include/internal/metacall.h
new file mode 100644 (file)
index 0000000..886f49f
--- /dev/null
@@ -0,0 +1,99 @@
+// -*- C++ -*-
+
+/*
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ *
+ * metacall.h
+ *
+ * This is an internal header file defining part of the metacall
+ * interface used by Cilkscreen.  It is not a stable API and is
+ * subject to change without notice.
+ */
+
+// Provides the enum of metacall kinds.  This is used by Cilkscreen and the
+// runtime, and will probably be used by any future ptools.
+
+#pragma once
+
+///////////////////////////////////////////////////////////////////////////////
+
+enum
+{
+    // Notify Cilkscreen to stop/start instrumenting code
+    HYPER_DISABLE_INSTRUMENTATION = 0,
+    HYPER_ENABLE_INSTRUMENTATION = 1,
+
+    // Write 0 in *(char *)arg if the p-tool is sequential.  The Cilk runtime
+    // system invokes this metacall to know whether to spawn worker threads.
+    HYPER_ZERO_IF_SEQUENTIAL_PTOOL = 2,
+
+    // Write 0 in *(char *)arg if the runtime must force reducers to
+    // call the reduce() method even if no actual stealing occurs.
+    HYPER_ZERO_IF_FORCE_REDUCE = 3,
+
+    // Inform cilkscreen about the current stack pointer.
+    HYPER_ESTABLISH_C_STACK = 4,
+
+    // Inform Cilkscreen about the current worker
+    HYPER_ESTABLISH_WORKER = 5,
+
+    // Tell tools to ignore a block of memory.  Parameter is a 2 element
+    // array: void *block[2] = {_begin, _end};  _end is 1 beyond the end
+    // of the block to be ignored.  Essentially, if p is a pointer to an
+    // array, _begin = &p[0], _end = &p[max]
+    HYPER_IGNORE_MEMORY_BLOCK = 6
+
+    // If you add metacalls here, remember to update BOTH workspan.cpp AND
+    // cilkscreen-common.cpp!
+};
+
+typedef struct
+{
+    unsigned int tool;  // Specifies tool metacall is for
+                        // (eg. system=0, cilkscreen=1, cilkview=2).
+                        // All tools should understand system codes.
+                        // Tools should ignore all other codes, except
+                        // their own.
+
+    unsigned int code;  // Tool-specific code specifies what to do and how to
+                        // interpret data
+
+    void        *data;
+} metacall_data_t;
+
+#define METACALL_TOOL_SYSTEM 0
+
+///////////////////////////////////////////////////////////////////////////////
diff --git a/libcilkrts/include/internal/rev.mk b/libcilkrts/include/internal/rev.mk
new file mode 100644 (file)
index 0000000..f65ad6d
--- /dev/null
@@ -0,0 +1,41 @@
+#########################################################################
+#
+#  @copyright
+#  Copyright (C) 2011-2013, Intel Corporation
+#  All rights reserved.
+#  
+#  @copyright
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions
+#  are met:
+#  
+#    * Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#    * Neither the name of Intel Corporation nor the names of its
+#      contributors may be used to endorse or promote products derived
+#      from this software without specific prior written permission.
+#  
+#  @copyright
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+#  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+#  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+#  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+#  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+###########################################################################
+
+# DO NOT EDIT THIS FILE!
+#
+# It was automatically generated by cilkrts/include/internal/Makefile
+
+CILK_REVISION = 3902
diff --git a/libcilkrts/mk/cilk-version.mk b/libcilkrts/mk/cilk-version.mk
new file mode 100644 (file)
index 0000000..76f3f4e
--- /dev/null
@@ -0,0 +1,61 @@
+#########################################################################
+#
+#  @copyright
+#  Copyright (C) 2009-2013, Intel Corporation
+#  All rights reserved.
+#  
+#  @copyright
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions
+#  are met:
+#  
+#    * Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#    * Neither the name of Intel Corporation nor the names of its
+#      contributors may be used to endorse or promote products derived
+#      from this software without specific prior written permission.
+#  
+#  @copyright
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+#  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+#  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+#  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+#  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+###########################################################################
+# cilk-version.mk
+#
+# The one place we look up information from the code management system
+#
+# Note that the build number is *only* valid on the build machines
+
+ifeq ($(wildcard $(TOP)/../.hg),)
+  # If this is the open source release, there is no Mercurial repository,
+  # so set some reasonable defaults.
+  CILK_VERSION_MAJOR := 2
+  CILK_VERSION_MINOR := 0
+  CILK_VERSION_BUILD := 1
+  CILK_VERSION_REV   := 0
+
+  CILK_VERSION_HASH  := 000000000000
+  CILK_VERSION_BRANCH := oss
+else
+  CILK_VERSION_MAJOR := 2
+  CILK_VERSION_MINOR := 0
+  CILK_VERSION_BUILD := $(firstword $(subst +, ,$(shell hg id --num)))
+  CILK_VERSION_REV   := 0
+
+  CILK_VERSION_HASH := $(firstword $(subst +, ,$(shell hg id --id)))
+  CILK_VERSION_BRANCH := $(shell hg id --branch)
+endif
+
diff --git a/libcilkrts/runtime/acknowledgements.dox b/libcilkrts/runtime/acknowledgements.dox
new file mode 100644 (file)
index 0000000..79b5d87
--- /dev/null
@@ -0,0 +1,51 @@
+/* acknowledgements.dox\r
+ *\r
+ *************************************************************************\r
+ *\r
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/\r
+\r
+/*\r
+ * This file contains acknowledgements of community contributions to the\r
+ * Cilk Plus runtime.\r
+ */\r
+\r
+/**\r
+ * @mainpage\r
+ *\r
+ * @section Acknowledgements Acknowledgements\r
+ *\r
+ * Modifications to build the Cilk Plus runtime for VxWorks provided by\r
+ * Brian Kuhl of Wind River.\r
+ */\r
diff --git a/libcilkrts/runtime/bug.cpp b/libcilkrts/runtime/bug.cpp
new file mode 100644 (file)
index 0000000..dbdf1fd
--- /dev/null
@@ -0,0 +1,139 @@
+/* bug.cpp                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#include "bug.h"
+
+#include <exception>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#ifdef _WIN32
+#   include "windows-clean.h"
+#   include "internal/abi.h"
+#   include "cilktools/cilkscreen.h"
+#   include <crtdbg.h>
+#endif
+
+__CILKRTS_BEGIN_EXTERN_C
+
+COMMON_PORTABLE const char *const __cilkrts_assertion_failed =
+    "%s:%d: cilk assertion failed: %s\n";
+
+COMMON_PORTABLE void __cilkrts_bug(const char *fmt,...) cilk_nothrow
+{
+#if defined (_WIN32) && defined(_DEBUG)
+    _CRTIMP void __cdecl _wassert(__in_z const wchar_t * _Message,
+                                  __in_z const wchar_t *_File,
+                                  __in unsigned _Line);
+    char message[256];
+    wchar_t wmessage[256];
+    va_list l;
+    va_start(l, fmt);
+    _vsnprintf_s(message, 256, _TRUNCATE, fmt, l);
+    va_end(l);
+    _snwprintf_s(wmessage, 256, _TRUNCATE, _CRT_WIDE("%S"),
+                 message); /* widen */
+
+    // Force asserts to go to stderr and the debugger.  This isn't polite, but
+    // we're about to kill the app anyway and it will prevent our tests from
+    // hanging
+    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE| _CRTDBG_MODE_DEBUG);
+    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
+
+    _wassert(wmessage, _CRT_WIDE(__FILE__), __LINE__);
+
+    // If there's a debugger attached, give it a chance to look at the failure
+    if (IsDebuggerPresent())
+        DebugBreak();
+
+    abort();
+/*    __asm int 3 */
+#else
+    /* To reduce user confusion, write all user-generated output
+       before the system-generated error message. */
+    va_list l;
+    fflush(NULL);
+    va_start(l, fmt);
+    vfprintf(stderr, fmt, l);
+    va_end(l);
+    fflush(stderr);
+
+#ifndef _WIN32
+    abort();
+#endif
+
+#endif
+
+    exit(1);
+}
+
+COMMON_PORTABLE void cilkbug_assert_no_uncaught_exception(void)
+{
+    bool uncaught = std::uncaught_exception();
+    CILK_ASSERT(!uncaught);
+}
+
+COMMON_SYSDEP void abort_because_rts_is_corrupted(void)
+{
+    __cilkrts_bug("The Cilk Plus runtime system detected a corruption "
+                  "in its data structures.  This is most likely caused "
+                  "by an application bug.  Aborting execution.\n");
+}
+
+#ifdef WIN32
+COMMON_SYSDEP void __cilkrts_dbgprintf(const char *fmt,...)
+{
+    char message[2048];
+    va_list l;
+
+    // Cilkscreen shouldn't watch this
+    __cilkscreen_disable_checking();
+
+    va_start(l, fmt);
+    _vsnprintf_s(message, 2048, _TRUNCATE, fmt, l);
+    va_end(l);
+    OutputDebugStringA (message);
+
+    // Re-enable Cilkscreen
+    __cilkscreen_enable_checking();
+}
+#endif
+
+__CILKRTS_END_EXTERN_C
+
+/* End bug.cpp */
diff --git a/libcilkrts/runtime/bug.h b/libcilkrts/runtime/bug.h
new file mode 100644 (file)
index 0000000..bb18913
--- /dev/null
@@ -0,0 +1,141 @@
+/* bug.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file bug.h
+ *
+ * @brief Support for reporting bugs and debugging.
+ */
+
+#ifndef INCLUDED_BUG_DOT_H
+#define INCLUDED_BUG_DOT_H
+
+#include "rts-common.h"
+#include <cilk/common.h>
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * Flush all output, write error message to stderr and abort the execution.
+ * On Windows the error is also written to the debugger.
+ *
+ * @param fmt printf-style format string.  Any remaining parameters will be
+ * be interpreted based on the format string text.
+ */
+COMMON_PORTABLE NORETURN __cilkrts_bug(const char *fmt,...) cilk_nothrow;
+
+#ifndef CILK_ASSERT
+
+/** Standard text for failed assertion */
+COMMON_PORTABLE extern const char *const __cilkrts_assertion_failed;
+
+/**
+ * Macro to assert an invariant that must be true.  If the statement evalutes
+ * to false, __cilkrts_bug will be called to report the failure and terminate
+ * the application.
+ */
+#define CILK_ASSERT(ex)                                                 \
+    (__builtin_expect((ex) != 0, 1) ? (void)0 :                         \
+     __cilkrts_bug(__cilkrts_assertion_failed, __FILE__, __LINE__,  #ex))
+
+#define CILK_ASSERT_MSG(ex, msg)                                        \
+    (__builtin_expect((ex) != 0, 1) ? (void)0 :                         \
+     __cilkrts_bug(__cilkrts_assertion_failed, __FILE__, __LINE__,      \
+                   #ex "\n    " msg))
+#endif  // CILK_ASSERT
+
+/**
+ * Assert that there is no uncaught exception.
+ *
+ * Not valid on Windows or Android.
+ *
+ * On Android, calling std::uncaught_exception with the stlport library causes
+ * a seg fault.  Since we're not supporting exceptions there at this point,
+ * just don't do the check.  It works with the GNU STL library, but that's
+ * GPL V3 licensed.
+ */
+COMMON_PORTABLE void cilkbug_assert_no_uncaught_exception(void);
+#if defined(_WIN32) || defined(ANDROID)
+#  define CILKBUG_ASSERT_NO_UNCAUGHT_EXCEPTION()
+#else
+#  define CILKBUG_ASSERT_NO_UNCAUGHT_EXCEPTION() \
+    cilkbug_assert_no_uncaught_exception()
+#endif
+
+
+/**
+ * Call __cilkrts_bug with a standard message that the runtime state is
+ * corrupted and the application is being terminated.
+ */
+COMMON_SYSDEP void abort_because_rts_is_corrupted(void);
+
+// Debugging aids
+#ifndef _DEBUG
+#       define DBGPRINTF(_fmt, ...)
+#elif defined(_WIN32)
+
+/**
+ * Write debugging output.  On windows this is written to the debugger.
+ *
+ * @param fmt printf-style format string.  Any remaining parameters will be
+ * be interpreted based on the format string text.
+ */
+COMMON_SYSDEP void __cilkrts_dbgprintf(const char *fmt,...) cilk_nothrow;
+
+/**
+ * Macro to write debugging output which will be elided if this is not a
+ * debug build.  The macro is currently always elided on non-Windows builds.
+ *
+ * @param _fmt printf-style format string.  Any remaining parameters will be
+ * be interpreted based on the format string text.
+ */
+#       define DBGPRINTF(_fmt, ...) __cilkrts_dbgprintf(_fmt, __VA_ARGS__)
+
+#else /* if _DEBUG && !_WIN32 */
+    /* Non-Windows debug logging.  Someday we should make GetCurrentFiber()
+     * and GetWorkerFiber() do something.
+     */
+#   include <stdio.h>
+    __CILKRTS_INLINE void* GetCurrentFiber() { return 0; }
+    __CILKRTS_INLINE void* GetWorkerFiber(__cilkrts_worker* w) { return 0; }
+#       define DBGPRINTF(_fmt, ...) fprintf(stderr, _fmt, __VA_ARGS__)
+#endif  // _DEBUG
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_BUG_DOT_H)
diff --git a/libcilkrts/runtime/c_reducers.c b/libcilkrts/runtime/c_reducers.c
new file mode 100644 (file)
index 0000000..52615e9
--- /dev/null
@@ -0,0 +1,57 @@
+/* c_reducers.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2010-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+/* Implementation of C reducers */
+
+// Disable warning about integer conversions losing significant bits.
+// The code is correct as is.
+#ifdef __INTEL_COMPILER
+#pragma warning(disable:2259)
+#endif
+
+#define CILK_C_DEFINE_REDUCERS
+
+#include <cilk/reducer_opadd.h>
+#include <cilk/reducer_opand.h>
+#include <cilk/reducer_opmul.h>
+#include <cilk/reducer_opor.h>
+#include <cilk/reducer_opxor.h>
+#include <cilk/reducer_min_max.h>
+
+/* End reducer_opadd.c */
diff --git a/libcilkrts/runtime/cilk-abi-cilk-for.cpp b/libcilkrts/runtime/cilk-abi-cilk-for.cpp
new file mode 100644 (file)
index 0000000..4fa6dce
--- /dev/null
@@ -0,0 +1,406 @@
+/* cilk-abi-cilk-for.cpp                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2011, 2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+/* Implementation of cilk_for ABI.
+ *
+ * This file must be C++, not C, in order to handle C++ exceptions correctly
+ * from within the body of the cilk_for loop
+ */
+
+#include "internal/abi.h"
+#include "metacall_impl.h"
+#include "global_state.h"
+
+// Icky macros to determine if we're compiled with optimization.  Based on
+// the declaration of __CILKRTS_ASSERT in common.h
+#if defined(_WIN32)
+# if defined (_DEBUG)
+#   define CILKRTS_OPTIMIZED 0    // Assumes /MDd is always used with /Od
+# else
+#   define CILKRTS_OPTIMIZED 1
+# endif // defined(_DEBUG)
+#else
+# if defined(__OPTIMIZE__)
+#   define CILKRTS_OPTIMIZED 1
+# else
+#   define CILKRTS_OPTIMIZED 0
+# endif
+#endif
+
+template <typename count_t>
+static inline int grainsize(int req, count_t count)
+{
+    // A positive requested grain size comes from the user.  A very high grain
+    // size risks losing parallelism, but the user told us what they want for
+    // grainsize.  Who are we to argue?
+    if (req > 0)
+        return req;
+
+    // At present, a negative requested grain size is treated the same way as
+    // a zero grain size, i.e., the runtime computes the actual grainsize
+    // using a hueristic.  In the future, the compiler may give us additional
+    // information about the size of the cilk_for body by passing a negative
+    // grain size.
+
+    // Avoid generating a zero grainsize, even for empty loops.
+    if (count < 1)
+        return 1;
+
+    global_state_t* g = cilkg_get_global_state();
+    if (g->under_ptool)
+    {
+        // Grainsize = 1, when running under PIN, and when the grainsize has
+        // not explicitly been set by the user.
+        return 1;
+    }
+    else
+    {
+        // Divide loop count by 8 times the worker count and round up.
+        const int Px8 = g->P * 8;
+        count_t n = (count + Px8 - 1) / Px8;
+
+        // 2K should be enough to amortize the cost of the cilk_for. Any
+        // larger grainsize risks losing parallelism.
+        if (n > 2048)
+            return 2048;
+        return (int) n;  // n <= 2048, so no loss of precision on cast to int
+    }
+}
+
+/*
+ * call_cilk_for_loop_body
+ *
+ * Centralizes the code to call the loop body.  The compiler should be
+ * inlining this code
+ *
+ * low   - Low loop index we're considering in this portion of the algorithm
+ * high  - High loop index we're considering in this portion of the algorithm
+ * body  - lambda function for the cilk_for loop body
+ * data  - data used by the lambda function
+ * w     - __cilkrts_worker we're currently executing on
+ * loop_root_pedigree - __cilkrts_pedigree node we generated for the root of
+ *         the cilk_for loop to flatten out the internal nodes
+ */
+template <typename count_t, typename F>
+inline static
+void call_cilk_for_loop_body(count_t low, count_t high,
+                             F body, void *data,
+                             __cilkrts_worker *w,
+                             __cilkrts_pedigree *loop_root_pedigree)
+{
+    // Cilkscreen should not report this call in a stack trace
+    NOTIFY_ZC_INTRINSIC((char *)"cilkscreen_hide_call", 0);
+
+    // The worker is only valid until the first spawn.  Fetch the
+    // __cilkrts_stack_frame out of the worker, since it will be stable across
+    // steals.  The sf pointer actually points to the *parent's*
+    // __cilkrts_stack_frame, since this function is a non-spawning function
+    // and therefore has no cilk stack frame of its own.
+    __cilkrts_stack_frame *sf = w->current_stack_frame;
+
+    // Save the pedigree node pointed to by the worker.  We'll need to restore
+    // that when we exit since the spawn helpers in the cilk_for call tree
+    // will assume that it's valid
+    const __cilkrts_pedigree *saved_next_pedigree_node = w->pedigree.parent;
+
+    // Add the leaf pedigree node to the chain. The parent is the root node
+    // to flatten the tree regardless of the DAG branches in the cilk_for
+    // divide-and-conquer recursion.
+    //
+    // The rank is initialized to the low index.  The user is
+    // expected to call __cilkrts_bump_loop_rank at the end of the cilk_for
+    // loop body.
+    __cilkrts_pedigree loop_leaf_pedigree;
+
+    loop_leaf_pedigree.rank = (uint64_t)low;
+    loop_leaf_pedigree.parent = loop_root_pedigree;
+
+    // The worker's pedigree always starts with a rank of 0
+    w->pedigree.rank = 0;
+    w->pedigree.parent = &loop_leaf_pedigree;
+
+    // Call the compiler generated cilk_for loop body lambda function
+    body(data, low, high);
+
+    // The loop body may have included spawns, so we must refetch the worker
+    // from the __cilkrts_stack_frame, which is stable regardless of which
+    // worker we're executing on.
+    w = sf->worker;
+
+    // Restore the pedigree chain. It must be valid because the spawn helpers
+    // generated by the cilk_for implementation will access it.
+    w->pedigree.parent = saved_next_pedigree_node;
+}
+
+/* capture_spawn_arg_stack_frame
+ *
+ * Efficiently get the address of the caller's __cilkrts_stack_frame.  The
+ * preconditons are that 'w' is the worker at the time of the call and
+ * 'w->current_stack_frame' points to the __cilkrts_stack_frame within the
+ * spawn helper.  This function should be called only within the argument list
+ * of a function that is being spawned because that is the only situation in
+ * which these preconditions hold.  This function returns the worker
+ * (unchanged) after storing the captured stack frame pointer is stored in the
+ * sf argument.
+ *
+ * The purpose of this function is to get the caller's stack frame in a
+ * context where the caller's worker is known but its stack frame is not
+ * necessarily initialized.  The "shrink wrap" optimization delays
+ * initializing the contents of a spawning function's '__cilkrts_stack_frame'
+ * as well as the 'current_stack_frame' pointer within the worker.  By calling
+ * this function within a spawning function's argument list, we can ensure
+ * that these initializations have occured but that a detach (which would
+ * invalidate the worker pointer in the caller) has not yet occured.  Once the
+ * '__cilkrts_stack_frame' has been retrieved in this way, it is stable for the
+ * remainder of the caller's execution, and becomes an efficient way to get
+ * the worker (much more efficient than calling '__cilkrts_get_tls_worker()'),
+ * even after a spawn or sync.
+ */
+inline __cilkrts_worker* 
+capture_spawn_arg_stack_frame(__cilkrts_stack_frame* &sf, __cilkrts_worker* w)
+{
+    // Get current stack frame
+    sf = w->current_stack_frame;
+#ifdef __INTEL_COMPILER
+#   if __INTEL_COMPILER <= 1300 && __INTEL_COMPILER_BUILD_DATE < 20130101
+    // In older compilers 'w->current_stack_frame' points to the
+    // spawn-helper's stack frame.  In newer compiler's however, it points
+    // directly to the pointer's stack frame.  (This change was made to avoid
+    // having the spawn helper in the frame list when evaluating function
+    // arguments, thus avoiding corruption when those arguments themselves
+    // contain cilk_spawns.)
+    
+    // w->current_stack_frame is the spawn helper's stack frame.
+    // w->current_stack_frame->call_parent is the caller's stack frame.
+    sf = sf->call_parent;
+#   endif
+#endif
+    return w;
+}
+
+/*
+ * cilk_for_recursive
+ *
+ * Templatized function to implement the recursive divide-and-conquer
+ * algorithm that's how we implement a cilk_for.
+ *
+ * low   - Low loop index we're considering in this portion of the algorithm
+ * high  - High loop index we're considering in this portion of the algorithm
+ * body  - lambda function for the cilk_for loop body
+ * data  - data used by the lambda function
+ * grain - grain size (0 if it should be computed)
+ * w     - __cilkrts_worker we're currently executing on
+ * loop_root_pedigree - __cilkrts_pedigree node we generated for the root of
+ *         the cilk_for loop to flatten out the internal nodes
+ */
+template <typename count_t, typename F>
+static
+void cilk_for_recursive(count_t low, count_t high,
+                        F body, void *data, int grain,
+                        __cilkrts_worker *w,
+                        __cilkrts_pedigree *loop_root_pedigree)
+{
+tail_recurse:
+    // Cilkscreen should not report this call in a stack trace
+    // This needs to be done everytime the worker resumes
+    NOTIFY_ZC_INTRINSIC((char *)"cilkscreen_hide_call", 0);
+
+    count_t count = high - low;
+    // Invariant: count > 0, grain >= 1
+    if (count > grain)
+    {
+        // Invariant: count >= 2
+        count_t mid = low + count / 2;
+        // The worker is valid only until the first spawn and is expensive to
+        // retrieve (using '__cilkrts_get_tls_worker') after the spawn.  The
+        // '__cilkrts_stack_frame' is more stable, but isn't initialized until
+        // the first spawn.  Thus, we want to grab the address of the
+        // '__cilkrts_stack_frame' after it is initialized but before the
+        // spawn detaches.  The only place we can do that is within the
+        // argument list of the spawned function, hence the call to
+        // capture_spawn_arg_stack_frame().
+        __cilkrts_stack_frame *sf;
+        _Cilk_spawn cilk_for_recursive(low, mid, body, data, grain,
+                                       capture_spawn_arg_stack_frame(sf, w),
+                                       loop_root_pedigree);
+        w = sf->worker;
+        low = mid;
+
+        goto tail_recurse;
+    }
+
+    // Call the cilk_for loop body lambda function passed in by the compiler to
+    // execute one grain
+    call_cilk_for_loop_body(low, high, body, data, w, loop_root_pedigree);
+}
+
+static void noop() { }
+
+/*
+ * cilk_for_root
+ *
+ * Templatized function to implement the top level of a cilk_for loop.
+ *
+ * body  - lambda function for the cilk_for loop body
+ * data  - data used by the lambda function
+ * count - trip count for loop
+ * grain - grain size (0 if it should be computed)
+ */
+template <typename count_t, typename F>
+static void cilk_for_root(F body, void *data, count_t count, int grain)
+{
+    // Cilkscreen should not report this call in a stack trace
+    NOTIFY_ZC_INTRINSIC((char *)"cilkscreen_hide_call", 0);
+
+    // Pedigree computation:
+    //
+    //    If the last pedigree node on entry to the _Cilk_for has value X,
+    //    then at the start of each iteration of the loop body, the value of
+    //    the last pedigree node should be 0, the value of the second-to-last
+    //    node should equal the loop counter, and the value of the
+    //    third-to-last node should be X.  On return from the _Cilk_for, the
+    //    value of the last pedigree should be incremented to X+2. The
+    //    pedigree within the loop is thus flattened, such that the depth of
+    //    recursion does not affect the results either inside or outside of
+    //    the loop.  Note that the pedigree after the loop exists is the same
+    //    as if a single spawn and sync were executed within this function.
+
+    // TBD: Since the shrink-wrap optimization was turned on in the compiler,
+    // it is not possible to get the current stack frame without actually
+    // forcing a call to bind-thread.  This spurious spawn is a temporary
+    // stopgap until the correct intrinsics are added to give us total control
+    // over frame initialization.
+    _Cilk_spawn noop();
+
+    // Fetch the current worker.  From that we can get the current stack frame
+    // which will be constant even if we're stolen
+    __cilkrts_worker *w = __cilkrts_get_tls_worker();
+    __cilkrts_stack_frame *sf = w->current_stack_frame;
+
+    // Decrement the rank by one to undo the pedigree change from the
+    // _Cilk_spawn
+    --w->pedigree.rank;
+
+    // Save the current worker pedigree into loop_root_pedigree, which will be
+    // the root node for our flattened pedigree.
+    __cilkrts_pedigree loop_root_pedigree = w->pedigree;
+
+    // Don't splice the loop_root node in yet.  It will be done when we
+    // call the loop body lambda function
+//    w->pedigree.rank = 0;
+//    w->pedigree.next = &loop_root_pedigree;
+
+    /* Spawn is necessary at top-level to force runtime to start up.
+     * Runtime must be started in order to call the grainsize() function.
+     */
+    int gs = grainsize(grain, count);
+    cilk_for_recursive((count_t) 0, count, body, data, gs, w,
+                       &loop_root_pedigree);
+
+    // Need to refetch the worker after calling a spawning function.
+    w = sf->worker;
+
+    // Restore the pedigree in the worker.
+    w->pedigree = loop_root_pedigree;
+
+    // Bump the worker pedigree.
+    ++w->pedigree.rank;
+
+    // Implicit sync will increment the pedigree leaf rank again, for a total
+    // of two increments.  If the noop spawn above is removed, then we'll need
+    // to re-enable the following code:
+//     // If this is an optimized build, then the compiler will have optimized
+//     // out the increment of the worker's pedigree in the implied sync.  We
+//     // need to add one to make the pedigree_loop test work correctly.
+// #if CILKRTS_OPTIMIZED
+//     ++sf->worker->pedigree.rank;
+// #endif
+}
+
+// Use extern "C" to suppress name mangling of __cilkrts_cilk_for_32 and
+// __cilkrts_cilk_for_64.
+extern "C" {
+
+/*
+ * __cilkrts_cilk_for_32
+ *
+ * Implementation of cilk_for for 32-bit trip counts (regardless of processor
+ * word size).  Assumes that the range is 0 - count.
+ *
+ * body  - lambda function for the cilk_for loop body
+ * data  - data used by the lambda function
+ * count - trip count for loop
+ * grain - grain size (0 if it should be computed)
+ */
+
+CILK_ABI_THROWS_VOID __cilkrts_cilk_for_32(__cilk_abi_f32_t body, void *data,
+                                            cilk32_t count, int grain)
+{
+    // Cilkscreen should not report this call in a stack trace
+    NOTIFY_ZC_INTRINSIC((char *)"cilkscreen_hide_call", 0);
+
+    // Check for an empty range here as an optimization - don't need to do any
+    // __cilkrts_stack_frame initialization
+    if (count > 0)
+        cilk_for_root(body, data, count, grain);
+}
+
+/*
+ * __cilkrts_cilk_for_64
+ *
+ * Implementation of cilk_for for 64-bit trip counts (regardless of processor
+ * word size).  Assumes that the range is 0 - count.
+ *
+ * body  - lambda function for the cilk_for loop body
+ * data  - data used by the lambda function
+ * count - trip count for loop
+ * grain - grain size (0 if it should be computed)
+ */
+CILK_ABI_THROWS_VOID __cilkrts_cilk_for_64(__cilk_abi_f64_t body, void *data,
+                                            cilk64_t count, int grain)
+{
+    // Check for an empty range here as an optimization - don't need to do any
+    // __cilkrts_stack_frame initialization
+    if (count > 0)
+        cilk_for_root(body, data, count, grain);
+}
+
+} // end extern "C"
+
+/* End cilk-abi-cilk-for.cpp */
diff --git a/libcilkrts/runtime/cilk-abi-vla-internal.c b/libcilkrts/runtime/cilk-abi-vla-internal.c
new file mode 100644 (file)
index 0000000..6fb9267
--- /dev/null
@@ -0,0 +1,83 @@
+/* cilk-abi-vla-internal.c        -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/*
+ * These functions are provided in their own compilation unit so I can debug
+ * them.  cilk-abi-vla.c must always be compiled with optimization on so that
+ * inlining occurs.
+ */
+
+#include "internal/abi.h"
+#include "cilk-abi-vla-internal.h"
+#include "bug.h"
+#include "full_frame.h"
+#include "local_state.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "bug.h"
+
+void *vla_internal_heap_alloc(__cilkrts_stack_frame *sf,
+                              size_t full_size,
+                              uint32_t align)
+{
+    return malloc(full_size);
+}
+
+void vla_internal_heap_free(void *t, size_t size)
+{
+    free(t);
+}
+
+void vla_free_from_original_stack(__cilkrts_stack_frame *sf,
+                                  size_t full_size)
+{
+    // The __cilkrts_stack_frame must be initialized
+    CILK_ASSERT(sf->worker);
+
+#if 1
+    // Add full_size to ff->sync_sp so that when we return, the VLA will no
+    // longer be allocated on the stack
+    __cilkrts_adjust_stack(sf->worker->l->frame_ff, full_size);
+#else
+    // Inline __cilkrts_adjust_stack for Kevin
+    full_frame *ff = sf->worker->l->frame_ff;
+    ff->sync_sp = ff->sync_sp + full_size;
+#endif
+}
diff --git a/libcilkrts/runtime/cilk-abi-vla-internal.h b/libcilkrts/runtime/cilk-abi-vla-internal.h
new file mode 100644 (file)
index 0000000..909f08f
--- /dev/null
@@ -0,0 +1,90 @@
+/* cilk-abi-vla-internal.h        -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file cilk-abi-vla-internal.h
+ *
+ * @brief Allocation/deallocation function for use with Variable Length
+ * Arrays in spawning functions.
+ *
+ * These should be the only functions in the Cilk runtime allocating memory
+ * from the standard C runtime heap.  This memory will be provided to user
+ * code for use in VLAs, when the memory cannot be allocated from the stack.
+ *
+ * While these functions are simply passthroughs to malloc and free at the
+ * moment, once we've got the basics of VLA allocations working we'll make
+ * them do fancier tricks.
+ */
+
+/**
+ * @brief Allocate memory from the heap for use by a Variable Length Array in
+ * a spawning function.
+ *
+ * @param sf The __cilkrts_stack_frame for the spawning function containing
+ * the VLA.
+ * @param full_size The number of bytes to be allocated, including any tags
+ * needed to identify this as allocated from the heap.
+ * @param align Any alignment necessary for the allocation.
+ */
+
+void *vla_internal_heap_alloc(__cilkrts_stack_frame *sf,
+                              size_t full_size,
+                              uint32_t align);
+
+/**
+ * @brief Deallocate memory from the heap used by a Variable Length Array in
+ * a spawning function.
+ *
+ * @param t The address of the memory block to be freed.
+ * @param size The size of the memory block to be freed.
+ */
+
+void vla_internal_heap_free(void *t,
+                            size_t size);
+
+/**
+ * @brief Deallocate memory from the original stack.  We'll do this by adding
+ * full_size to ff->sync_sp.  So after the sync, the Variable Length Array
+ * will no longer be allocated on the stack.
+ *
+ * @param sf The __cilkrts_stack_frame for the spawning function that is
+ * deallocating a VLA.
+ * @param full_size The size of the VLA, including any alignment and tags.
+ */
+void vla_free_from_original_stack(__cilkrts_stack_frame *sf,
+                                  size_t full_size);
diff --git a/libcilkrts/runtime/cilk-abi.c b/libcilkrts/runtime/cilk-abi.c
new file mode 100644 (file)
index 0000000..1da0523
--- /dev/null
@@ -0,0 +1,733 @@
+/* Cilk_abi.c                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2010-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+/**
+ * @file cilk-abi.c
+ *
+ * @brief cilk-abi.c implements all of the entrypoints to the Intel Cilk
+ * Plus runtime.
+ */
+
+/*
+ * Define this macro so that compiliation of this file generates the
+ * non-inlined versions of certain functions in cilk_api.h.
+ */
+#include "internal/abi.h"
+#include "cilk/cilk_api.h"
+#include "cilk/cilk_undocumented.h"
+#include "cilktools/cilkscreen.h"
+
+#include "global_state.h"
+#include "os.h"
+#include "os_mutex.h"
+#include "bug.h"
+#include "local_state.h"
+#include "full_frame.h"
+#include "pedigrees.h"
+#include "scheduler.h"
+#include "sysdep.h"
+#include "except.h"
+#include "cilk_malloc.h"
+#include "record-replay.h"
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef _MSC_VER
+/* Some versions of icc don't support limits.h on Linux if
+   gcc 4.3 or newer is installed. */
+#include <limits.h>
+
+/* Declare _ReturnAddress compiler intrinsic */
+void * _ReturnAddress(void);
+#pragma intrinsic(_ReturnAddress)
+
+#include "sysdep-win.h"     // Needed for sysdep_init_module()
+#endif  /* _WIN32 */
+
+#include "metacall_impl.h"
+#include "reducer_impl.h"
+#include "cilk-ittnotify.h"
+#include "cilk-tbb-interop.h"
+
+#define TBB_INTEROP_DATA_DELAYED_UNTIL_BIND (void *)-1
+
+/**
+ * __cilkrts_bind_thread is a versioned entrypoint.  The runtime should be
+ * exporting copies of __cilkrts_bind_version for the current and all previous
+ * versions of the ABI.
+ *
+ * This macro should always be set to generate a version to match the current
+ * version; __CILKRTS_ABI_VERSION.
+ */
+#define BIND_THREAD_RTN __cilkrts_bind_thread_1
+
+static inline
+void enter_frame_internal(__cilkrts_stack_frame *sf, uint32_t version)
+{
+    __cilkrts_worker *w = __cilkrts_get_tls_worker();
+    if (w == 0) { /* slow path */
+        w = BIND_THREAD_RTN();
+
+        sf->flags = CILK_FRAME_LAST | (version << 24);
+        CILK_ASSERT((sf->flags & CILK_FRAME_FLAGS_MASK) == CILK_FRAME_LAST);
+    } else {
+        sf->flags = (version << 24);
+        CILK_ASSERT((sf->flags & CILK_FRAME_FLAGS_MASK) == 0);
+    }
+    sf->call_parent = w->current_stack_frame;
+    sf->worker = w;
+    w->current_stack_frame = sf;
+}
+
+CILK_ABI_VOID __cilkrts_enter_frame(__cilkrts_stack_frame *sf)
+{
+    enter_frame_internal(sf, 0);
+}
+
+CILK_ABI_VOID __cilkrts_enter_frame_1(__cilkrts_stack_frame *sf)
+{
+    enter_frame_internal(sf, 1);
+    sf->reserved = 0;
+}
+
+static inline
+void enter_frame_fast_internal(__cilkrts_stack_frame *sf, uint32_t version)
+{
+    __cilkrts_worker *w = __cilkrts_get_tls_worker_fast();
+    sf->flags = version << 24;
+    sf->call_parent = w->current_stack_frame;
+    sf->worker = w;
+    w->current_stack_frame = sf;
+}
+
+CILK_ABI_VOID __cilkrts_enter_frame_fast(__cilkrts_stack_frame *sf)
+{
+    enter_frame_fast_internal(sf, 0);
+}
+
+CILK_ABI_VOID __cilkrts_enter_frame_fast_1(__cilkrts_stack_frame *sf)
+{
+    enter_frame_fast_internal(sf, 1);
+    sf->reserved = 0;
+}
+
+/**
+ * A component of the THE protocol.  __cilkrts_undo_detach checks whether
+ * this frame's parent has been stolen.  If it hasn't, the frame can return
+ * normally.  If the parent has been stolen, of if we suspect it might be,
+ * then __cilkrts_leave_frame() needs to call into the runtime.
+ *
+ * @note __cilkrts_undo_detach() is comparing the exception pointer against
+ * the tail pointer.  The exception pointer is modified when another worker
+ * is considering whether it can steal a frame.  The head pointer is updated
+ * to match when the worker lock is taken out and the thief is sure that
+ * it can complete the steal.  If the steal cannot be completed, the thief
+ * will restore the exception pointer.
+ *
+ * @return true if undo-detach failed.
+ */
+static int __cilkrts_undo_detach(__cilkrts_stack_frame *sf)
+{
+    __cilkrts_worker *w = sf->worker;
+    __cilkrts_stack_frame *volatile *t = w->tail;
+
+/*    DBGPRINTF("%d - __cilkrts_undo_detach - sf %p\n", w->self, sf); */
+
+    --t;
+    w->tail = t;
+    /* On x86 the __sync_fetch_and_<op> family includes a
+       full memory barrier.  In theory the sequence in the
+       second branch of the #if should be faster, but on
+       most x86 it is not.  */
+#if defined __i386__ || defined __x86_64__
+    __sync_fetch_and_and(&sf->flags, ~CILK_FRAME_DETACHED);
+#else
+    __cilkrts_fence(); /* membar #StoreLoad */
+    sf->flags &= ~CILK_FRAME_DETACHED;
+#endif
+
+    return __builtin_expect(t < w->exc, 0);
+}
+
+CILK_ABI_VOID __cilkrts_leave_frame(__cilkrts_stack_frame *sf)
+{
+    __cilkrts_worker *w = sf->worker;
+
+/*    DBGPRINTF("%d-%p __cilkrts_leave_frame - sf %p, flags: %x\n", w->self, GetWorkerFiber(w), sf, sf->flags); */
+
+#ifdef _WIN32
+    /* if leave frame was called from our unwind handler, leave_frame should
+       proceed no further. */
+    if (sf->flags & CILK_FRAME_UNWINDING)
+    {
+/*        DBGPRINTF("%d - __cilkrts_leave_frame - aborting due to UNWINDING flag\n", w->self); */
+
+        // If this is the frame of a spawn helper (indicated by the
+        // CILK_FRAME_DETACHED flag) we must update the pedigree.  The pedigree
+        // points to nodes allocated on the stack.  Failing to update it will
+        // result in a accvio/segfault if the pedigree is walked.  This must happen
+        // for all spawn helper frames, even if we're processing an exception
+        if ((sf->flags & CILK_FRAME_DETACHED))
+        {
+           update_pedigree_on_leave_frame(w, sf);
+        }
+        return;
+    }
+#endif
+
+#if CILK_LIB_DEBUG
+    /* ensure the caller popped itself */
+    CILK_ASSERT(w->current_stack_frame != sf);
+#endif
+
+    /* The exiting function should have checked for zero flags,
+       so there is no check for flags == 0 here. */
+
+#if CILK_LIB_DEBUG
+    if (__builtin_expect(sf->flags & (CILK_FRAME_EXITING|CILK_FRAME_UNSYNCHED), 0))
+        __cilkrts_bug("W%u: function exiting with invalid flags %02x\n",
+                      w->self, sf->flags);
+#endif
+
+    /* Must return normally if (1) the active function was called
+       and not spawned, or (2) the parent has never been stolen. */
+    if ((sf->flags & CILK_FRAME_DETACHED)) {
+/*        DBGPRINTF("%d - __cilkrts_leave_frame - CILK_FRAME_DETACHED\n", w->self); */
+
+#ifndef _WIN32
+        if (__builtin_expect(sf->flags & CILK_FRAME_EXCEPTING, 0)) {
+// Pedigree will be updated in __cilkrts_leave_frame.  We need the
+// pedigree before the update for record/replay
+//         update_pedigree_on_leave_frame(w, sf);
+            __cilkrts_return_exception(sf);
+            /* If return_exception returns the caller is attached.
+               leave_frame is called from a cleanup (destructor)
+               for the frame object.  The caller will reraise the
+               exception. */
+           return;
+        }
+#endif
+
+        // During replay, check whether w was the last worker to continue
+        replay_wait_for_steal_if_parent_was_stolen(w);
+
+        // Attempt to undo the detach
+        if (__builtin_expect(__cilkrts_undo_detach(sf), 0)) {
+               // The update of pedigree for leaving the frame occurs
+               // inside this call if it does not return.
+            __cilkrts_c_THE_exception_check(w, sf);
+        }
+
+        update_pedigree_on_leave_frame(w, sf);
+
+        /* This path is taken when undo-detach wins the race with stealing.
+           Otherwise this strand terminates and the caller will be resumed
+           via setjmp at sync. */
+        if (__builtin_expect(sf->flags & CILK_FRAME_FLAGS_MASK, 0))
+            __cilkrts_bug("W%u: frame won undo-detach race with flags %02x\n",
+                          w->self, sf->flags);
+
+        return;
+    }
+
+#if CILK_LIB_DEBUG
+    sf->flags |= CILK_FRAME_EXITING;
+#endif
+
+    if (__builtin_expect(sf->flags & CILK_FRAME_LAST, 0))
+        __cilkrts_c_return_from_initial(w); /* does return */
+    else if (sf->flags & CILK_FRAME_STOLEN)
+        __cilkrts_return(w); /* does return */
+
+/*    DBGPRINTF("%d-%p __cilkrts_leave_frame - returning, StackBase: %p\n", w->self, GetWorkerFiber(w)); */
+}
+
+/* Caller must have called setjmp. */
+CILK_ABI_VOID __cilkrts_sync(__cilkrts_stack_frame *sf)
+{
+    __cilkrts_worker *w = sf->worker;
+/*    DBGPRINTF("%d-%p __cilkrts_sync - sf %p\n", w->self, GetWorkerFiber(w), sf); */
+    if (__builtin_expect(!(sf->flags & CILK_FRAME_UNSYNCHED), 0))
+        __cilkrts_bug("W%u: double sync %p\n", w->self, sf);
+#ifndef _WIN32
+    if (__builtin_expect(sf->flags & CILK_FRAME_EXCEPTING, 0)) {
+        __cilkrts_c_sync_except(w, sf);
+    }
+#endif
+
+    __cilkrts_c_sync(w, sf);
+}
+
+/*
+ * __cilkrts_get_sf
+ *
+ * Debugging aid to provide access to the current __cilkrts_stack_frame.
+ *
+ * Not documented!
+ */
+
+CILK_API_VOID_PTR
+__cilkrts_get_sf(void)
+{
+    __cilkrts_worker *w = __cilkrts_get_tls_worker();
+    if (0 == w)
+        return NULL;
+
+    return w->current_stack_frame;
+}
+
+/* Call with global lock held */
+static __cilkrts_worker *find_free_worker(global_state_t *g)
+{
+    __cilkrts_worker *w = 0;
+    int i;
+
+    // Scan the non-system workers looking for one which is free so we can
+    // use it.
+    for (i = g->P - 1; i < g->total_workers; ++i) {
+        w = g->workers[i];
+        CILK_ASSERT(WORKER_SYSTEM != w->l->type);
+        if (w->l->type == WORKER_FREE) {
+            w->l->type = WORKER_USER;
+            w->l->team = w;
+            return w;
+        }
+    }
+
+    // If we ran out of workers, create a new one.  It doesn't actually belong
+    // to the Cilk global state so nobody will ever try to steal from it.
+    w = (__cilkrts_worker *)__cilkrts_malloc(sizeof(*w));
+    __cilkrts_cilkscreen_ignore_block(w, w+1);
+    make_worker(g, -1, w);
+    w->l->type = WORKER_USER;
+    w->l->team = w;
+    return w;
+}
+
+/*
+ * __cilkrts_bind_thread
+ *
+ * Exported function to bind a thread to the runtime.
+ *
+ * This function name should always have a trailing suffix for the latest ABI
+ * version. This means that code built with a new compiler will not load
+ * against an old copy of the runtime.
+ *
+ * Symbols for the function called by code compiled with old versions of the
+ * compiler are created in an OS-specific manner:
+ *  - On Windows the old symbols are defined in the cilk-exports.def linker
+ *    definitions file as aliases of BIND_THREAD_RTN
+ *  - On Linux aliased symbols are created for BIND_THREAD_RTN in this file
+ *  - On MacOS the alternate entrypoints are implemented and simply call
+ *    BIND_THREAD_RTN.
+ */
+CILK_ABI_WORKER_PTR BIND_THREAD_RTN(void)
+{
+    __cilkrts_worker *w;
+    int start_cilkscreen = 0;
+#ifdef USE_ITTNOTIFY
+    static int unique_obj;
+#endif
+
+    // Cannot set this pointer until after __cilkrts_init_internal() call:
+    global_state_t* g;
+
+    ITT_SYNC_CREATE (&unique_obj, "Initialization");
+    ITT_SYNC_PREPARE(&unique_obj);
+    ITT_SYNC_ACQUIRED(&unique_obj);
+
+
+    /* 1: Initialize and start the Cilk runtime */
+    __cilkrts_init_internal(1);
+
+    /*
+     * 2: Choose a worker for this thread (fail if none left).  The table of
+     *    user workers is protected by the global OS mutex lock.
+     */
+    g = cilkg_get_global_state();
+    global_os_mutex_lock();
+    if (__builtin_expect(g->work_done, 0))
+        __cilkrts_bug("Attempt to enter Cilk while Cilk is shutting down");
+    w = find_free_worker(g);
+    CILK_ASSERT(w);
+
+    __cilkrts_set_tls_worker(w);
+    __cilkrts_cilkscreen_establish_worker(w);
+    {
+        full_frame *ff = __cilkrts_make_full_frame(w, 0);
+
+        ff->fiber_self = cilk_fiber_allocate_from_thread();
+        CILK_ASSERT(ff->fiber_self);
+
+        cilk_fiber_set_owner(ff->fiber_self, w);
+        cilk_fiber_tbb_interop_use_saved_stack_op_info(ff->fiber_self);
+       
+        CILK_ASSERT(ff->join_counter == 0);
+        ff->join_counter = 1;
+        w->l->frame_ff = ff;
+        w->reducer_map = __cilkrts_make_reducer_map(w);
+        __cilkrts_set_leftmost_reducer_map(w->reducer_map, 1);
+        load_pedigree_leaf_into_user_worker(w);
+    }
+
+    // Make sure that the head and tail are reset, and saved_protected_tail
+    // allows all frames to be stolen.
+    //
+    // Note that we must NOT check w->exc, since workers that are trying to
+    // steal from it will be updating w->exc and we don't own the worker lock.
+    // It's not worth taking out the lock just for an assertion.
+    CILK_ASSERT(w->head == w->l->ltq);
+    CILK_ASSERT(w->tail == w->l->ltq);
+    CILK_ASSERT(w->protected_tail  == w->ltq_limit);
+
+    // There may have been an old pending exception which was freed when the
+    // exception was caught outside of Cilk
+    w->l->pending_exception = NULL;
+
+    w->reserved = NULL;
+
+    // If we've already created a scheduling fiber for this worker, we'll just
+    // reuse it.  If w->self < 0, it means that this is an ad-hoc user worker
+    // not known to the global state.  Thus, we need to create a scheduling
+    // stack only if we don't already have one and w->self >= 0.
+    if (NULL == w->l->scheduling_fiber && w->self >= 0)
+    {
+        START_INTERVAL(w, INTERVAL_FIBER_ALLOCATE) {
+            // Create a scheduling fiber for this worker.
+            w->l->scheduling_fiber =
+                cilk_fiber_allocate_from_heap(CILK_SCHEDULING_STACK_SIZE);
+            cilk_fiber_reset_state(w->l->scheduling_fiber,
+                                   scheduler_fiber_proc_for_user_worker);
+            cilk_fiber_set_owner(w->l->scheduling_fiber, w);
+        } STOP_INTERVAL(w, INTERVAL_FIBER_ALLOCATE);
+    }
+    
+    // If the scheduling fiber is NULL, we've either exceeded our quota for
+    // fibers or workers or we're out of memory, so we should lose parallelism
+    // by disallowing stealing.
+    if (NULL == w->l->scheduling_fiber)
+        __cilkrts_disallow_stealing(w, NULL);
+
+    start_cilkscreen = (0 == w->g->Q);
+
+    if (w->self != -1) {
+        // w->self != -1, means that w is a normal user worker and must be
+        // accounted for by the global state since other workers can steal from
+        // it.
+
+        // w->self == -1, means that w is an overflow worker and was created on
+        // demand.  I.e., it does not need to be accounted for by the global
+        // state.
+
+        __cilkrts_enter_cilk(w->g);
+    }
+
+    global_os_mutex_unlock();
+
+    /* If there's only 1 worker, the counts will be started in
+     * __cilkrts_scheduler */
+    if (g->P > 1)
+    {
+        START_INTERVAL(w, INTERVAL_IN_SCHEDULER);
+        START_INTERVAL(w, INTERVAL_WORKING);
+    }
+
+    ITT_SYNC_RELEASING(&unique_obj);
+
+    /* Turn on Cilkscreen if this is the first worker.  This needs to be done
+     * when we are NOT holding the os mutex. */
+    if (start_cilkscreen)
+        __cilkrts_cilkscreen_enable_instrumentation();
+
+    return w;
+}
+
+#ifndef _MSC_VER
+/*
+ * Define old version-specific symbols for binding threads (since they exist in
+ * all Cilk code).  These aliases prohibit newly compiled code from loading an
+ * old version of the runtime.  We can handle old code with a new runtime, but
+ * new code with an old runtime is verboten!
+ *
+ * For Windows, the aliased symbol is exported in cilk-exports.def.
+ */
+#if defined(_DARWIN_C_SOURCE) || defined(__APPLE__)
+/**
+ * Mac OS X: Unfortunately, Darwin doesn't allow aliasing, so we just make a
+ * call and hope the optimizer does the right thing.
+ */
+CILK_ABI_WORKER_PTR __cilkrts_bind_thread (void) {
+    return BIND_THREAD_RTN();
+}
+#else
+
+/**
+ * Macro to convert a parameter to a string.  Used on Linux or BSD.
+ */
+#define STRINGIFY(x) #x
+
+/**
+ * Macro to generate an __attribute__ for an aliased name
+ */
+#define ALIASED_NAME(x) __attribute__ ((alias (STRINGIFY(x))))
+
+/**
+ * Linux or BSD: Use the alias attribute to make the labels for the versioned
+ * functions point to the same place in the code as the original.  Using
+ * the two macros is annoying but required.
+ */
+
+CILK_ABI_WORKER_PTR __cilkrts_bind_thread(void)
+    ALIASED_NAME(BIND_THREAD_RTN);
+
+#endif // defined _DARWIN_C_SOURCE || defined __APPLE__
+#endif // !defined _MSC_VER
+
+CILK_API_SIZET
+__cilkrts_get_stack_size(void) {
+    return cilkg_get_stack_size();
+}
+
+// Method for debugging.
+CILK_API_VOID __cilkrts_dump_stats(void)
+{
+    // While the stats aren't protected by the global OS mutex, the table
+    // of workers is, so take out the global OS mutex while we're doing this
+    global_os_mutex_lock();
+    if (cilkg_is_published()) {
+        global_state_t *g = cilkg_get_global_state();
+       __cilkrts_dump_stats_to_stderr(g);
+    }
+    else {
+       __cilkrts_bug("Attempting to report Cilk stats before the runtime has started\n");
+    }    
+    global_os_mutex_unlock();
+}
+
+#ifndef _WIN32
+CILK_ABI_THROWS_VOID __cilkrts_rethrow(__cilkrts_stack_frame *sf)
+{
+    __cilkrts_gcc_rethrow(sf);
+}
+#endif
+
+/*
+ * __cilkrts_unwatch_stack
+ *
+ * Callback for TBB to tell us they don't want to watch the stack anymore
+ */
+
+static __cilk_tbb_retcode __cilkrts_unwatch_stack(void *data)
+{
+    __cilk_tbb_stack_op_thunk o;
+
+    // If the cilk_fiber wasn't available fetch it now
+    if (TBB_INTEROP_DATA_DELAYED_UNTIL_BIND == data)
+    {
+        full_frame *ff;
+        __cilkrts_worker *w = __cilkrts_get_tls_worker();
+        if (NULL == w)
+        {
+            // Free any saved stack op information
+            cilk_fiber_tbb_interop_free_stack_op_info();
+
+            return 0;       /* Success! */
+        }
+
+        __cilkrts_worker_lock(w);
+        ff = w->l->frame_ff;
+        __cilkrts_frame_lock(w,ff);
+        data = ff->fiber_self;
+        __cilkrts_frame_unlock(w,ff);
+        __cilkrts_worker_unlock(w);
+    }
+
+#if CILK_LIB_DEBUG /* Debug code */
+    /* Get current stack */
+    full_frame *ff;
+    __cilkrts_worker *w = __cilkrts_get_tls_worker();
+    __cilkrts_worker_lock(w);
+    ff = w->l->frame_ff;
+    __cilkrts_frame_lock(w,ff);
+    CILK_ASSERT (data == ff->fiber_self);
+    __cilkrts_frame_unlock(w,ff);
+    __cilkrts_worker_unlock(w);
+#endif
+
+    /* Clear the callback information */
+    o.data = NULL;
+    o.routine = NULL;
+    cilk_fiber_set_stack_op((cilk_fiber*)data, o);
+    
+    // Note. Do *NOT* free any saved stack information here.   If they want to
+    // free the saved stack op information, they'll do it when the thread is
+    // unbound
+
+    return 0;       /* Success! */
+}
+
+/*
+ * __cilkrts_watch_stack
+ *
+ * Called by TBB, defined by Cilk.
+ *
+ * Requests that Cilk invoke the stack op routine when it orphans a stack. 
+ * Cilk sets *u to a thunk that TBB should call when it is no longer interested
+ * in watching the stack.
+ */
+
+CILK_API_TBB_RETCODE
+__cilkrts_watch_stack(__cilk_tbb_unwatch_thunk *u,
+                      __cilk_tbb_stack_op_thunk o)
+{
+    cilk_fiber* current_fiber;
+    __cilkrts_worker *w;
+
+#ifdef _MSC_VER
+    // This may be called by TBB *before* the OS has given us our
+    // initialization call.  Make sure the module is initialized.
+    sysdep_init_module();
+#endif
+
+    // Fetch the __cilkrts_worker bound to this thread
+    w = __cilkrts_get_tls_worker();
+    if (NULL == w)
+    {
+        // Save data for later.  We'll deal with it when/if this thread binds
+        // to the runtime
+        cilk_fiber_tbb_interop_save_stack_op_info(o);
+        
+        u->routine = __cilkrts_unwatch_stack;
+        u->data = TBB_INTEROP_DATA_DELAYED_UNTIL_BIND;
+
+        return 0;
+    }
+
+    /* Get current stack */
+    __cilkrts_worker_lock(w);
+    current_fiber = w->l->frame_ff->fiber_self;
+    __cilkrts_worker_unlock(w);
+
+/*    CILK_ASSERT( !sd->stack_op_data ); */
+/*    CILK_ASSERT( !sd->stack_op_routine ); */
+
+    /* Give TBB our callback */
+    u->routine = __cilkrts_unwatch_stack;
+    u->data = current_fiber;
+    /* Save the callback information */
+    cilk_fiber_set_stack_op(current_fiber, o);
+
+    return 0;   /* Success! */
+}
+
+
+// This function must be called only within a continuation, within the stack
+// frame of the continuation itself.
+CILK_API_INT __cilkrts_synched(void)
+{
+    __cilkrts_worker *w = __cilkrts_get_tls_worker();
+
+    // If we don't have a worker, then we're synched by definition :o)
+    if (NULL == w)
+        return 1;
+
+    // Check to see if we are in a stolen continuation.  If not, then
+    // we are synched.
+    uint32_t flags = w->current_stack_frame->flags;
+    if (0 == (flags & CILK_FRAME_UNSYNCHED))
+        return 1;
+
+    // We are in a stolen continutation, but the join counter might have been
+    // decremented to one, making us synched again.  Get the full frame so
+    // that we can check the join counter.  ASSUME: frame_ff is stable (can be
+    // read without a lock) in a stolen continuation -- it can't be stolen
+    // while it's currently executing.
+    full_frame *ff = w->l->frame_ff;
+
+    // Make sure we have a full frame
+    // TBD: Don't think that we should ever not have a full frame here.
+    // CILK_ASSERT(NULL != ff); ?
+    if (NULL == ff)
+        return 1;
+
+    // We're synched if there are no outstanding children at this instant in
+    // time.  Note that this is a known race, but it's ok since we're only
+    // reading.  We can get false negatives, but not false positives. (I.e.,
+    // we can read a non-one join_counter just before it goes to one, but the
+    // join_counter cannot go from one to greater than one while we're
+    // reading.)
+    return 1 == ff->join_counter;
+}
+
+
+
+
+CILK_API_INT
+__cilkrts_bump_loop_rank_internal(__cilkrts_worker* w)
+{
+    // If we don't have a worker, then the runtime is not bound to this
+    // thread and there is no rank to increment
+    if (NULL == w)
+        return -1;
+
+    // We're at the start of the loop body.  Advance the cilk_for loop
+    // body pedigree by following the parent link and updating its
+    // rank.
+
+    // Normally, we'd just write "w->pedigree.parent->rank++"
+    // But we need to cast away the "const".
+    ((__cilkrts_pedigree*) w->pedigree.parent)->rank++;
+
+    // Zero the worker's pedigree rank since this is the start of a new
+    // pedigree domain.
+    w->pedigree.rank = 0;
+
+    return 0;
+}
+
+CILK_ABI_VOID
+__cilkrts_save_fp_ctrl_state(__cilkrts_stack_frame *sf)
+{
+    // Pass call onto OS/architecture dependent function
+    sysdep_save_fp_ctrl_state(sf);
+}
+
+/* end cilk-abi.c */
diff --git a/libcilkrts/runtime/cilk-ittnotify.h b/libcilkrts/runtime/cilk-ittnotify.h
new file mode 100644 (file)
index 0000000..ff995db
--- /dev/null
@@ -0,0 +1,100 @@
+/* cilk-ittnotify.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#ifndef INCLUDED_CILK_ITTNOTIFY_DOT_H
+#define INCLUDED_CILK_ITTNOTIFY_DOT_H
+
+#ifdef __INTEL_COMPILER
+#endif
+#include <stdio.h>
+
+// ITTNOTIFY does not support ARM at this time
+#ifdef __arm__
+#undef USE_ITTNOTIFY
+#endif
+
+#ifdef USE_ITTNOTIFY
+#include <ittnotify.h>
+
+#ifdef _WIN32
+# define ITT_SYNC_CREATE(_address, _description)        \
+    __itt_sync_createA(_address,                        \
+                       "Intel Cilk Plus " _description, \
+                       "",                              \
+                       __itt_attr_barrier)
+#else
+# define ITT_SYNC_CREATE(_address, _description)        \
+    __itt_sync_create(_address,                         \
+                      "Intel Cilk Plus " _description,  \
+                      "",                               \
+                      __itt_attr_barrier)
+#endif
+
+#define ITT_SYNC_PREPARE(_address) __itt_sync_prepare(_address)
+#define ITT_SYNC_ACQUIRED(_address) __itt_sync_acquired(_address)
+#define ITT_SYNC_RELEASING(_address) __itt_sync_releasing(_address)
+#define ITT_SYNC_DESTROY(_address) __itt_sync_destroy(_address)
+// Note that we subtract 5 from the return address to find the CALL instruction
+// to __cilkrts_sync
+#if 1   // Disable renaming for now.  Piersol isn't ready yet
+#define ITT_SYNC_SET_NAME_AND_PREPARE(_address, _sync_ret_address) __itt_sync_prepare(_address)
+#else
+#define ITT_SYNC_SET_NAME_AND_PREPARE(_address, _sync_ret_address) \
+    if (NULL != __itt_sync_prepare_ptr) {   \
+        if (0 == _sync_ret_address) \
+            __itt_sync_renameA(_address, "");  \
+        else    \
+        {   \
+            char buf[128];  \
+            sprintf_s(buf, 128, "IP:0x%p", (DWORD_PTR)_sync_ret_address - 5); \
+            __itt_sync_renameA(_address, buf); \
+            _sync_ret_address = 0;  \
+         }  \
+        __itt_sync_prepare(_address);  \
+    }
+#endif
+#else   // USE_ITTNOTIFY not defined, compile out all calls
+#define ITT_SYNC_CREATE(_address, _description)
+#define ITT_SYNC_PREPARE(_address)
+#define ITT_SYNC_ACQUIRED(_address)
+#define ITT_SYNC_RELEASING(_addresss)
+#define ITT_SYNC_DESTROY(_address)
+#define ITT_SYNC_SET_NAME_AND_PREPARE(_sync_address, _wait_address)
+#endif
+
+#endif // ! defined(INCLUDED_CILK_ITTNOTIFY_DOT_H)
diff --git a/libcilkrts/runtime/cilk-tbb-interop.h b/libcilkrts/runtime/cilk-tbb-interop.h
new file mode 100644 (file)
index 0000000..cc5cff4
--- /dev/null
@@ -0,0 +1,192 @@
+/* cilk-tbb-interop.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file cilk-tbb-interop.h
+ *
+ * @brief Interface between TBB and Cilk to allow TBB to associate it's
+ * per-thread data with Cilk workers, and maintain the association as work
+ * moves between worker threads.  This handles the case where TBB calls
+ * into a Cilk function which may later call back to a function making
+ * TBB calls.
+ *
+ * Each thunk structure has two pointers: \"routine\" and \"data\".
+ * The caller of the thunk invokes *routine, passing \"data\" as the void*
+ * parameter.
+ */
+
+#ifndef INCLUDED_CILK_TBB_INTEROP_DOT_H
+#define INCLUDED_CILK_TBB_INTEROP_DOT_H
+
+#include <cilk/common.h>  // for CILK_EXPORT
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/** A return code.  0 indicates success. */
+typedef int __cilk_tbb_retcode;
+
+/**
+ * Enumeration of reasons that Cilk will call the TBB stack operation
+ * function.
+ *
+ * When a non-empty stack is transfered between threads, the first thread must
+ * orphan it and the second thread must adopt it.
+ *
+ * An empty stack can be transfered similarly, or simply released by the first
+ * thread.
+ *
+ * Here is a summary of the actions as transitions on a state machine.
+@verbatim
+                       watch                                    ORPHAN
+                       -->-->                                   -->--
+                      /      \                                 /     \
+   (freed empty stack)       (TBB sees stack running on thread)      (stack in limbo)
+                      \     /                                  \     / 
+                       --<--                                    --<--
+                       RELEASE or                               ADOPT
+                       unwatch
+@endverbatim
+ */
+typedef enum __cilk_tbb_stack_op {
+   /**
+    * Disconnecting stack from a thread.
+    *
+    * The thunk must be invoked on the thread disconnecting itself from the
+    * stack.  Must \"happen before\" the stack is adopted elsewhere.
+    */
+    CILK_TBB_STACK_ORPHAN,
+
+    /**
+     * Reconnecting orphaned stack to a thread.
+     *
+     * The thunk must be invoked on the thread adopting the stack.
+     */
+    CILK_TBB_STACK_ADOPT,
+
+   /**
+    * Releasing stack.
+    *
+    * The thunk must be invoked on the thread doing the releasing, Must
+    * \"happen before\" the stack is used elsewhere.
+    */
+    CILK_TBB_STACK_RELEASE
+} __cilk_tbb_stack_op;
+
+/**
+ * Function that will be called by the Cilk runtime to inform TBB of a change
+ * in the stack associated with the current thread.
+ *
+ * It does not matter what stack the thunk runs on.
+ * The thread (not fiber) on which the thunk runs is important.
+ *
+ * @param op Enumerated value indicating what type of change is ocurring.
+ * @param data Context value provided by TBB in the __cilkrts_watch_stack
+ * call.  This data is opaque to Cilk.
+ *
+ * @return 0 indicates success.
+ */
+typedef __cilk_tbb_retcode (*__cilk_tbb_pfn_stack_op)(enum __cilk_tbb_stack_op op,
+                                                      void* data);
+
+/**
+ * Function that will be called by TBB to inform the Cilk runtime that TBB
+ * is no longer interested in watching the stack bound to the current thread.
+ *
+ * @param data Context value provided to TBB by the __cilkrts_watch_stack
+ * call.  This data is opaque to TBB.
+ *
+ * @return 0 indicates success.
+ */
+typedef __cilk_tbb_retcode (*__cilk_tbb_pfn_unwatch_stacks)(void *data);
+
+/**
+ * Thunk invoked by Cilk to call back to TBB to tell it about a change in
+ * the stack bound to the current thread.
+ */
+typedef struct __cilk_tbb_stack_op_thunk {
+    /// Function in TBB the Cilk runtime should call when something
+    // "interesting" happens involving a stack
+    __cilk_tbb_pfn_stack_op routine;
+
+    /// TBB context data to pass with the call to the stack_op routine
+    void* data;
+} __cilk_tbb_stack_op_thunk;
+
+/**
+ * Thunk invoked by TBB when it is no longer interested in watching the stack
+ * bound to the current thread.
+ */
+typedef struct __cilk_tbb_unwatch_thunk {
+    /// Function in Cilk runtime to call when TBB no longer wants to watch
+    // stacks
+    __cilk_tbb_pfn_unwatch_stacks routine;
+
+    /// Cilk runtime context data to pass with the call to the unwatch_stacks
+    /// routine
+    void* data;
+} __cilk_tbb_unwatch_thunk;
+
+/**
+ * Requests that Cilk invoke __cilk_tbb_orphan_thunk when it orphans a stack.
+ * Cilk sets *u to a thunk that TBB should call when it is no longer
+ * interested in watching the stack.
+ *
+ * If the thread is not yet bound to the Cilk runtime, the Cilk runtime should
+ * save this data in thread-local storage until __cilkrts_bind_thread is called.
+ *
+ * Called by TBB, defined by Cilk.  This function is exported from the Cilk
+ * runtime DLL/shared object.  This declaration also appears in
+ * cilk/cilk_undocumented.h -- don't change one declaration without also
+ * changing the other.
+ *
+ * @param u __cilk_tbb_unwatch_thunk.  This structure will be filled in by
+ * the Cilk runtime to allow TBB to register that it is no longer interested
+ * in watching the stack bound to the current thread.
+ * @param o __cilk_tbb_stack_op_thunk.  This structure specifies the routine
+ * that the Cilk runtime should call when an "interesting" change in the stack
+ * associate with the current worker occurs.
+ *
+ * @return 0 indicates success.
+ */
+CILK_EXPORT
+__cilk_tbb_retcode __cilkrts_watch_stack(__cilk_tbb_unwatch_thunk* u,
+                                         __cilk_tbb_stack_op_thunk o);
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_CILK_TBB_INTEROP_DOT_H)
diff --git a/libcilkrts/runtime/cilk_api.c b/libcilkrts/runtime/cilk_api.c
new file mode 100644 (file)
index 0000000..bbca984
--- /dev/null
@@ -0,0 +1,255 @@
+/* cilk_api.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/*
+ * Implementation of functions declared in cilk_api.h
+ */
+
+/*
+ * Define the COMPILING_CILK_ABI_FUNCTIONS macro, so that
+ * compilation of this file generates non-inlined definitions for the
+ * functions marked as CILK_EXPORT_AND_INLINE in cilk_api.h.
+ *
+ * We must deal with these functions differently because we need to
+ * continue to ship nonlined versions of these functions.
+ *
+ *   CILK_EXPORT_AND_INLINE int __cilkrts_get_worker_rank(uint64_t *rank);
+ *   CILK_EXPORT_AND_INLINE int __cilkrts_bump_worker_rank();
+ *   CILK_EXPORT_AND_INLINE int __cilkrts_bump_loop_rank();
+ */
+#define COMPILING_CILK_API_FUNCTIONS
+
+#include <internal/abi.h>
+#include <cilk/cilk_api.h>
+
+#include "os.h"
+#include "os_mutex.h"
+#include "bug.h"
+#include "global_state.h"
+#include "local_state.h"
+#include "scheduler.h"
+#include "sysdep.h"
+
+CILK_API_VOID __cilkrts_init(void)
+{
+    // Initialize, but don't start, the cilk runtime.
+    __cilkrts_init_internal(0);
+}
+
+CILK_API_VOID __cilkrts_end_cilk(void)
+{
+    // Take out the global OS mutex while we do this to protect against
+    // another thread attempting to bind while we do this
+    global_os_mutex_lock();
+
+    if (cilkg_is_published()) {
+        global_state_t *g = cilkg_get_global_state();
+        if (g->Q || __cilkrts_get_tls_worker())
+            __cilkrts_bug("Attempt to shut down Cilk while Cilk is still "
+                          "running");
+        __cilkrts_stop_workers(g);
+        __cilkrts_deinit_internal(g);
+    }
+
+    global_os_mutex_unlock();
+}
+
+CILK_API_INT
+__cilkrts_get_nworkers()
+{
+    return cilkg_get_nworkers();
+}
+
+CILK_API_INT
+__cilkrts_get_total_workers()
+{
+    return cilkg_get_total_workers();
+}
+
+CILK_API_INT __cilkrts_get_force_reduce(void)
+{
+    return cilkg_get_force_reduce();
+}
+
+CILK_API_INT __cilkrts_set_param(const char* param, const char* value)
+{
+    return cilkg_set_param(param, value);
+}
+
+#ifdef _WIN32
+CILK_API_INT __cilkrts_set_param_w(const wchar_t* param, const wchar_t* value)
+{
+    return cilkg_set_param_w(param, value);
+}
+#endif // _WIN32
+
+/* Return a small integer indicating which Cilk worker the function is
+ * currently running on.  Each thread started by the Cilk runtime library
+ * (system worker) has a unique worker number in the range 1..P-1, where P is
+ * the valued returned by __cilkrts_get_nworkers().  All threads started by
+ * the user or by other libraries (user workers) share the worker number 0.
+ * Therefore, the worker number is not unique across multiple user threads.
+ *
+ * Implementor's note: The value returned from this function is different from
+ * the value, w->self, used in most debug messages.
+ */
+CILK_API_INT
+__cilkrts_get_worker_number(void)
+{
+    __cilkrts_worker *w = __cilkrts_get_tls_worker();
+
+    if (0 == w)
+        /* A non-worker always has a worker number of zero. */
+        return 0;
+    else if (WORKER_USER == w->l->type)
+        /* User worker was once a non-worker, so its number should still be
+         * zero. */
+        return 0;
+    else
+        /* w->self for a system worker is in range 0..(P-1); adjust to 1..P
+         * to avoid conflicting with the user thread's worker number. */
+        return w->self + 1;
+}
+
+/**
+ * Internal definition of the pedigree context.  The size of the
+ * structure must match __cilkrts_pedigree_context_t defined in abi.i
+ */
+typedef struct pedigree_context_t
+{
+    /** Size of the structure, in bytes */
+    size_t size;
+
+    /** Next __cilkrts_pedigree to return */
+    const __cilkrts_pedigree *pedigree;
+
+    /** Unused.  Left over from previous implementation */
+    void *unused1;
+
+    /** Unused.  Left over from previous implementation */
+    void *unused2;
+
+    // // Debugging aid for pedigree-test:
+    // __cilkrts_stack_frame *expected_sf;
+} pedigree_context_t;
+
+/*
+ * __cilkrts_get_pedigree_info
+ *
+ * Fetch the birthrank for a stack frame.  To initialize the walk, both sf_in
+ * and frame_in should be NULL.  parent_sf_ptr and parent_frame_ptr provide
+ * context for the stackwalk and should be returned as sf_in and frame_in on
+ * the next call.
+ *
+ * Returns:
+ *   0 - Success - birthrank, parent_sf_out and parent_frame_out are valid
+ *   >1 - Pedigree walk completed
+ *   <1 - Failure - -1: No worker bound to thread, -2: Sanity check failed
+ */
+
+#define PEDIGREE_WALK_COMPLETE (__cilkrts_pedigree *)-1
+
+CILK_API_INT
+__cilkrts_get_pedigree_info(__cilkrts_pedigree_context_t *external_context,
+                            uint64_t *sf_birthrank)
+{
+    pedigree_context_t *context = (pedigree_context_t *)external_context;
+
+    CILK_ASSERT(sizeof(__cilkrts_pedigree_context_t) ==
+                sizeof(pedigree_context_t));
+    if (context->size != sizeof(pedigree_context_t))
+        return -3;  // Invalid size
+
+    // If the pointer to the last __cilkrts_pedigree is -1, we've
+    // finished the walk.  We're still done.
+    if (PEDIGREE_WALK_COMPLETE == context->pedigree)
+        return 1;
+
+    // The passed in context value contains a pointer to the last
+    // __cilkrts_pedigree returned, or NULL if we're starting a
+    // new walk
+    if (NULL == context->pedigree)
+    {
+        __cilkrts_worker *w = __cilkrts_get_tls_worker();
+       __cilkrts_pedigree* pedigree_node;
+        if (NULL != w) {
+           pedigree_node = &w->pedigree;
+       }
+       else {
+           pedigree_node = __cilkrts_get_tls_pedigree_leaf(1);
+       }
+       context->pedigree = pedigree_node->parent;
+    }
+    else
+        context->pedigree = context->pedigree->parent;
+
+    // Note: If we want to omit the user root node,
+    // stop at context->pedigree->parent instead.
+    if (NULL == context->pedigree)
+    {
+       context->pedigree = PEDIGREE_WALK_COMPLETE;
+        return 1;
+    }
+
+    *sf_birthrank = context->pedigree->rank;
+    return 0;
+}
+
+CILK_API_PEDIGREE
+__cilkrts_get_pedigree_internal(__cilkrts_worker *w)
+{
+    if (NULL != w) {
+       return w->pedigree;
+    }
+    else {
+       const __cilkrts_pedigree *pedigree =
+            __cilkrts_get_tls_pedigree_leaf(1);
+       return *pedigree;
+    }
+}
+
+
+CILK_API_INT __cilkrts_bump_worker_rank_internal(__cilkrts_worker *w)
+{
+    __cilkrts_pedigree *pedigree;
+    pedigree = (w ? &w->pedigree : __cilkrts_get_tls_pedigree_leaf(1));
+    pedigree->rank++;
+    return 0;
+}
+
+/* End cilk_api.c */
diff --git a/libcilkrts/runtime/cilk_fiber-unix.cpp b/libcilkrts/runtime/cilk_fiber-unix.cpp
new file mode 100644 (file)
index 0000000..b9b47e3
--- /dev/null
@@ -0,0 +1,273 @@
+/* cilk_fiber-unix.cpp                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2012-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#include "cilk_fiber-unix.h"
+#include "cilk_malloc.h"
+#include "bug.h"
+#include "os.h"
+
+#include <cstdio>
+#include <cstdlib>
+
+#include <alloca.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+// MAP_ANON is deprecated on Linux, but seems to be required on Mac...
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+// Magic number for sanity checking fiber structure
+const unsigned magic_number = 0x5afef00d;
+
+int cilk_fiber_sysdep::s_page_size = getpagesize();
+
+cilk_fiber_sysdep::cilk_fiber_sysdep(std::size_t stack_size)
+    : cilk_fiber(stack_size)
+    , m_magic(magic_number)
+{
+    // Set m_stack and m_stack_base.
+    make_stack(stack_size);
+
+    // Get high-address of stack, with 32-bytes of spare space, and rounded
+    // down to the nearest 32-byte boundary.
+    const uintptr_t align_mask = 32 - 1;
+    m_stack_base -= ((std::size_t) m_stack_base) & align_mask;
+}
+
+cilk_fiber_sysdep::cilk_fiber_sysdep(from_thread_t)
+    : cilk_fiber()
+    , m_magic(magic_number)
+{
+    this->set_allocated_from_thread(true);
+
+    // Dummy stack data for thread-main fiber
+    m_stack      = NULL;
+    m_stack_base = NULL;
+}
+
+void cilk_fiber_sysdep::convert_fiber_back_to_thread()
+{
+    // Does nothing on Linux.
+}
+
+cilk_fiber_sysdep::~cilk_fiber_sysdep()
+{
+    CILK_ASSERT(magic_number == m_magic);
+    if (!this->is_allocated_from_thread())
+        free_stack();
+}
+
+#if SUPPORT_GET_CURRENT_FIBER
+cilk_fiber_sysdep* cilk_fiber_sysdep::get_current_fiber_sysdep()
+{
+    return cilkos_get_tls_cilk_fiber();
+}
+#endif
+
+// Jump to resume other fiber.  We may or may not come back.
+inline void cilk_fiber_sysdep::resume_other_sysdep(cilk_fiber_sysdep* other)
+{
+    if (other->is_resumable()) {
+        other->set_resumable(false);
+        // Resume by longjmp'ing to the place where we suspended.
+        CILK_LONGJMP(other->m_resume_jmpbuf);
+    }
+    else {
+        // Otherwise, we've never ran this fiber before.  Start the
+        // proc method.
+        other->run();
+    }
+}
+
+void cilk_fiber_sysdep::suspend_self_and_resume_other_sysdep(cilk_fiber_sysdep* other)
+{
+#if SUPPORT_GET_CURRENT_FIBER
+    cilkos_set_tls_cilk_fiber(other);
+#endif
+    CILK_ASSERT(this->is_resumable());
+
+
+    // Jump to the other fiber.  We expect to come back.
+    if (! CILK_SETJMP(m_resume_jmpbuf)) {
+        resume_other_sysdep(other);
+    }
+
+    // Return here when another fiber resumes me.
+    // If the fiber that switched to me wants to be deallocated, do it now.
+    do_post_switch_actions();
+}
+
+NORETURN cilk_fiber_sysdep::jump_to_resume_other_sysdep(cilk_fiber_sysdep* other)
+{
+#if SUPPORT_GET_CURRENT_FIBER
+    cilkos_set_tls_cilk_fiber(other);
+#endif
+    CILK_ASSERT(!this->is_resumable());
+
+    // Jump to the other fiber.  But we are never coming back because
+    // this fiber is being reset.
+    resume_other_sysdep(other);
+
+    // We should never come back here...
+    __cilkrts_bug("Should not get here");
+}
+
+
+NORETURN cilk_fiber_sysdep::run()
+{
+    // Only fibers created from a pool have a proc method to run and execute. 
+    CILK_ASSERT(m_start_proc);
+    CILK_ASSERT(!this->is_allocated_from_thread());
+    CILK_ASSERT(!this->is_resumable());
+
+    // TBD: This setjmp/longjmp pair simply changes the stack pointer.
+    // We could probably replace this code with some assembly.
+    if (! CILK_SETJMP(m_resume_jmpbuf))
+    {
+        // Calculate the size of the current stack frame (i.e., this
+        // run() function.  
+        size_t frame_size = (size_t)JMPBUF_FP(m_resume_jmpbuf) - (size_t)JMPBUF_SP(m_resume_jmpbuf);
+
+        // Macs require 16-byte alignment.  Do it always because it just
+        // doesn't matter
+        if (frame_size & (16-1))
+            frame_size += 16 - (frame_size  & (16-1));
+
+        // Assert that we are getting a reasonable frame size out of
+        // it.  If this run() function is using more than 4096 bytes
+        // of space for its local variables / any state that spills to
+        // registers, something is probably *very* wrong here...
+        //
+        // 4096 bytes just happens to be a number that seems "large
+        // enough" --- for an example GCC 32-bit compilation, the
+        // frame size was 48 bytes.
+        CILK_ASSERT(frame_size < 4096);
+
+        // Change stack pointer to fiber stack.  Offset the
+        // calculation by the frame size, so that we've allocated
+        // enough extra space from the top of the stack we are
+        // switching to for any temporaries required for this run()
+        // function.
+        JMPBUF_SP(m_resume_jmpbuf) = m_stack_base - frame_size;
+        CILK_LONGJMP(m_resume_jmpbuf);
+    }
+
+    // Note: our resetting of the stack pointer is valid only if the
+    // compiler has not saved any temporaries onto the stack for this
+    // function before the longjmp that we still care about at this
+    // point.
+    
+    // Verify that 1) 'this' is still valid and 2) '*this' has not been
+    // corrupted.
+    CILK_ASSERT(magic_number == m_magic);
+
+    // If the fiber that switched to me wants to be deallocated, do it now.
+    do_post_switch_actions();
+
+    // Now call the user proc on the new stack
+    m_start_proc(this);
+
+    // alloca() to force generation of frame pointer.  The argument to alloca
+    // is contrived to prevent the compiler from optimizing it away.  This
+    // code should never actually be executed.
+    int* dummy = (int*) alloca((sizeof(int) + (std::size_t) m_start_proc) & 0x1);
+    *dummy = 0xface;
+
+    // User proc should never return.
+    __cilkrts_bug("Should not get here");
+}
+
+void cilk_fiber_sysdep::make_stack(size_t stack_size)
+{
+    char* p;
+    // We've already validated that the stack size is page-aligned and
+    // is a reasonable value.  No need to do any extra rounding here.
+    size_t rounded_stack_size = stack_size;
+
+    // Normally, we have already validated that the stack size is
+    // aligned to 4K.  In the rare case that pages are huge though, we
+    // need to do some extra checks.
+    if (rounded_stack_size < 3 * (size_t)s_page_size) {
+        // If the specified stack size is too small, round up to 3
+        // pages.  We need at least 2 extra for the guard pages.
+        rounded_stack_size = 3 * (size_t)s_page_size;
+    }
+    else {
+        // Otherwise, the stack size is large enough, but might not be
+        // a multiple of page size.  Round up to nearest multiple of
+        // s_page_size, just to be safe.
+        size_t remainder = rounded_stack_size % s_page_size;
+        if (remainder) {
+            rounded_stack_size += s_page_size - remainder;
+        }
+    }
+
+    p = (char*)mmap(0, rounded_stack_size,
+                    PROT_READ|PROT_WRITE,
+                    MAP_PRIVATE|MAP_ANONYMOUS,
+                    -1, 0);
+    if (MAP_FAILED == p) {
+        // For whatever reason (probably ran out of memory), mmap() failed.
+        // There is no stack to return, so the program loses parallelism.
+        m_stack = NULL;
+        m_stack_base = NULL;
+        return;
+    }
+
+    // mprotect guard pages.
+    mprotect(p + rounded_stack_size - s_page_size, s_page_size, PROT_NONE);
+    mprotect(p, s_page_size, PROT_NONE);
+
+    m_stack = p;
+    m_stack_base = p + rounded_stack_size - s_page_size;
+}
+
+
+void cilk_fiber_sysdep::free_stack()
+{
+    if (m_stack) {
+        size_t rounded_stack_size = m_stack_base - m_stack + s_page_size;
+        if (munmap(m_stack, rounded_stack_size) < 0)
+            __cilkrts_bug("Cilk: stack munmap failed error %d\n", errno);
+    }
+}
+
+/* End cilk_fiber-unix.cpp */
diff --git a/libcilkrts/runtime/cilk_fiber-unix.h b/libcilkrts/runtime/cilk_fiber-unix.h
new file mode 100644 (file)
index 0000000..9f47d5b
--- /dev/null
@@ -0,0 +1,149 @@
+/* cilk_fiber-unix.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2012-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#ifndef INCLUDED_CILK_FIBER_UNIX_DOT_H
+#define INCLUDED_CILK_FIBER_UNIX_DOT_H
+
+#ifndef __cplusplus
+#   error cilk_fiber-unix.h is a C++-only header
+#endif
+
+#include "cilk_fiber.h"
+#include "jmpbuf.h"
+
+/**
+ * @file cilk_fiber-unix.h
+ *
+ * @brief Unix-specific implementation for cilk_fiber.
+ */
+
+/**
+ * @brief Unix-specific fiber class derived from portable fiber class
+ */
+struct cilk_fiber_sysdep : public cilk_fiber
+{
+  public:
+
+#if SUPPORT_GET_CURRENT_FIBER
+    /**
+     * @brief Gets the current fiber from TLS.
+     */
+    static cilk_fiber_sysdep* get_current_fiber_sysdep();
+#endif
+
+    /**
+     * @brief Construct the system-dependent portion of a fiber.
+     *
+     * @param stack_size  The size of the stack for this fiber.
+     */ 
+    cilk_fiber_sysdep(std::size_t stack_size);
+
+    /**
+     * @brief Construct the system-dependent of a fiber created from a
+     * thread.
+     */ 
+    cilk_fiber_sysdep(from_thread_t);
+
+    /**
+     * @brief Destructor
+     */ 
+    ~cilk_fiber_sysdep();
+
+    /**
+     * @brief OS-specific calls to convert this fiber back to thread.
+     *
+     * Nothing to do for Linux.
+     */
+    void convert_fiber_back_to_thread();
+
+    /**
+     * @brief System-dependent function to suspend self and resume execution of "other".
+     *
+     * This fiber is suspended.
+     *          
+     * @pre @c is_resumable() should be true. 
+     *
+     * @param other              Fiber to resume.
+     */
+    void suspend_self_and_resume_other_sysdep(cilk_fiber_sysdep* other);
+
+    /**
+     * @brief System-dependent function called to jump to @p other
+     * fiber.
+     *
+     * @pre @c is_resumable() should be false.
+     *
+     * @param other  Fiber to resume.
+     */
+    NORETURN jump_to_resume_other_sysdep(cilk_fiber_sysdep* other);
+    
+    /**
+     * @brief Runs the start_proc.
+     * @pre is_resumable() should be false.
+     * @pre is_allocated_from_thread() should be false.
+     * @pre m_start_proc must be valid.
+     */
+    NORETURN run();
+
+    /**
+     * @brief Returns the base of this fiber's stack.
+     */
+    inline char* get_stack_base_sysdep() { return m_stack_base; }
+
+  private:
+    char*                       m_stack_base;     ///< The base of this fiber's stack.
+    char*                       m_stack;          // Stack memory (low address)
+    __CILK_JUMP_BUFFER          m_resume_jmpbuf;  // Place to resume fiber
+    unsigned                    m_magic;          // Magic number for checking
+
+    static int                  s_page_size;      // Page size for
+                                                  // stacks.
+
+    // Allocate memory for a stack.  This method
+    // initializes m_stack and m_stack_base.
+    void make_stack(size_t stack_size);
+
+    // Deallocates memory for the stack.
+    void free_stack();
+
+    // Common helper method for implementation of resume_other_sysdep
+    // variants.
+    inline void resume_other_sysdep(cilk_fiber_sysdep* other);
+};
+
+#endif // ! defined(INCLUDED_CILK_FIBER_UNIX_DOT_H)
diff --git a/libcilkrts/runtime/cilk_fiber.cpp b/libcilkrts/runtime/cilk_fiber.cpp
new file mode 100644 (file)
index 0000000..0c66f23
--- /dev/null
@@ -0,0 +1,1078 @@
+/* cilk_fiber.cpp                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2012-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/* Implementations of non-platform-specific aspects of cilk_fiber, especially
+ * the cilk_fiber_pool interface.
+ */
+#include "cilk_fiber.h"
+#ifdef _WIN32
+#   include "cilk_fiber-win.h"
+#else
+#   include "cilk_fiber-unix.h"
+#endif
+#include "cilk_malloc.h"
+#include "bug.h"
+#include <new>
+
+#include <climits>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#include "sysdep.h"
+
+
+extern "C" {
+
+inline int cilk_fiber_pool_sanity_check(cilk_fiber_pool *pool, const char* desc)
+{
+    int errors = 0;
+#if FIBER_DEBUG >= 1    
+    if ((NULL != pool) && pool->total > 0) {
+
+        // Root pool should not allocate more fibers than alloc_max
+        errors += ((pool->parent == NULL) &&
+                   (pool->total > pool->alloc_max));
+        errors += (pool->total > pool->high_water);
+
+        if (errors) {
+            fprintf(stderr, "ERROR at %s: pool=%p has max_size=%u, total=%d, high_water=%d\n",
+                    desc,
+                    pool, pool->max_size, pool->total, pool->high_water);
+        }
+    }
+#endif
+    return (errors == 0);
+}
+
+inline void increment_pool_total(cilk_fiber_pool* pool)
+{
+    ++pool->total;
+    if (pool->high_water < pool->total)
+        pool->high_water = pool->total;
+}
+
+inline void decrement_pool_total(cilk_fiber_pool* pool, int fibers_freed)
+{
+    pool->total -= fibers_freed;
+}
+
+
+/**
+ * @brief Free fibers from this pool until we have at most @c
+ * num_to_keep fibers remaining, and then put a fiber back.
+ *
+ * @pre   We do not hold @c pool->lock 
+ * @post  After completion, we do not hold @c pool->lock
+ */
+static void cilk_fiber_pool_free_fibers_from_pool(cilk_fiber_pool* pool,
+                                                  unsigned num_to_keep,
+                                                  cilk_fiber* fiber_to_return)
+{
+    // Free our own fibers, until we fall below our desired threshold.
+    // Each iteration of this loop proceeds in the following stages:
+    //   1.  Acquire the pool lock,
+    //   2.  Grabs up to B fibers from the pool, stores them into a buffer.
+    //   3.  Check if pool is empty enough.  If yes, put the last fiber back,
+    //       and remember that we should quit.
+    //   4.  Release the pool lock, and actually free any buffered fibers.
+    //   5.  Check if we are done and should exit the loop.  Otherwise, try again.
+    // 
+    const bool need_lock = pool->lock;
+    bool last_fiber_returned = false;
+    
+    do {
+        const int B = 10;   // Pull at most this many fibers from the
+                            // parent for one lock acquisition.  Make
+                            // this value large enough to amortize
+                            // against the cost of acquiring and
+                            // releasing the lock.
+        int num_to_free = 0;
+        cilk_fiber* fibers_to_free[B];
+
+        // Stage 1: Grab the lock.
+        if (need_lock) {
+            spin_mutex_lock(pool->lock);
+        }
+        
+        // Stage 2: Grab up to B fibers to free.
+        int fibers_freed = 0;
+        while ((pool->size > num_to_keep) && (num_to_free < B)) {
+            fibers_to_free[num_to_free++] = pool->fibers[--pool->size];
+            fibers_freed++;
+        }
+        decrement_pool_total(pool, fibers_freed);
+
+        // Stage 3.  Pool is below threshold.  Put extra fiber back.
+        if (pool->size <= num_to_keep) {
+            // Put the last fiber back into the pool.
+            if (fiber_to_return) {
+                CILK_ASSERT(pool->size < pool->max_size);
+                pool->fibers[pool->size] = fiber_to_return;
+                pool->size++;
+            }
+            last_fiber_returned = true;
+        }
+        
+        // Stage 4: Release the lock, and actually free any fibers
+        // buffered.
+        if (need_lock) {
+            spin_mutex_unlock(pool->lock);
+        }
+
+        for (int i = 0; i < num_to_free; ++i) {
+            fibers_to_free[i]->deallocate_to_heap();
+        }
+        
+    } while (!last_fiber_returned);
+}
+
+
+/******************************************************************
+ * TBD: We want to simplify / rework the logic for allocating and
+ * deallocating fibers, so that they are hopefully simpler and work
+ * more elegantly for more than two levels.
+ ******************************************************************/
+
+/**
+ * @brief Transfer fibers from @c pool to @c pool->parent.
+ *
+ * @pre   Must hold @c pool->lock if it exists.
+ * @post  After completion, some number of fibers
+ *        have been moved from this pool to the parent.
+ *        The lock @c pool->lock is still held.
+ *
+ * TBD: Do we wish to guarantee that the lock has never been
+ * released?  It may depend on the implementation...
+ */
+static void cilk_fiber_pool_move_fibers_to_parent_pool(cilk_fiber_pool* pool,
+                                                       unsigned num_to_keep)
+{
+    // ASSERT: We should hold the lock on pool (if it has one).
+    CILK_ASSERT(pool->parent);
+    cilk_fiber_pool* parent_pool = pool->parent;
+
+    // Move fibers from our pool to the parent until we either run out
+    // of space in the parent, or hit our threshold.
+    //
+    // This operation must be done while holding the parent lock.
+
+    // If the parent pool appears to be full, just return early.
+    if (parent_pool->size >= parent_pool->max_size)
+        return;
+
+    spin_mutex_lock(pool->parent->lock);
+    while ((parent_pool->size < parent_pool->max_size) &&
+           (pool->size > num_to_keep)) {
+        parent_pool->fibers[parent_pool->size++] =
+            pool->fibers[--pool->size];
+    }
+
+    // If the child pool has deallocated more than fibers to the heap
+    // than it has allocated, then transfer this "surplus" to the
+    // parent, so that the parent is free to allocate more from the
+    // heap.
+    // 
+    // This transfer means that the total in the parent can
+    // temporarily go negative.
+    if (pool->total < 0) {
+        // Reduce parent total by the surplus we have in the local
+        // pool.
+        parent_pool->total += pool->total;
+        pool->total = 0;
+    }
+
+    spin_mutex_unlock(pool->parent->lock);
+}
+    
+void cilk_fiber_pool_init(cilk_fiber_pool* pool,
+                          cilk_fiber_pool* parent,
+                          size_t           stack_size,
+                          unsigned         buffer_size,
+                          int              alloc_max,
+                          int              is_shared)
+{
+#if FIBER_DEBUG >= 1    
+    fprintf(stderr, "fiber_pool_init, pool=%p, parent=%p, alloc_max=%u\n",
+            pool, parent, alloc_max);
+#endif
+
+    pool->lock       = (is_shared ? spin_mutex_create() : NULL);
+    pool->parent     = parent;
+    pool->stack_size = stack_size;
+    pool->max_size   = buffer_size;
+    pool->size       = 0;
+    pool->total      = 0;
+    pool->high_water = 0;
+    pool->alloc_max  = alloc_max;
+    pool->fibers     =
+        (cilk_fiber**) __cilkrts_malloc(buffer_size * sizeof(cilk_fiber*));
+    CILK_ASSERT(NULL != pool->fibers);
+
+#ifdef __MIC__
+#define PREALLOCATE_FIBERS
+#endif
+    
+#ifdef PREALLOCATE_FIBERS
+    // Pre-allocate 1/4 of fibers in the pools ahead of time.  This
+    // value is somewhat arbitrary.  It was chosen to be less than the
+    // threshold (of about 3/4) of fibers to keep in the pool when
+    // transferring fibers to the parent.
+    
+    int pre_allocate_count = buffer_size/4;
+    for (pool->size = 0; pool->size < pre_allocate_count; pool->size++) {
+        pool->fibers[pool->size] = cilk_fiber::allocate_from_heap(pool->stack_size);
+    }
+#endif
+}
+
+
+void cilk_fiber_pool_set_fiber_limit(cilk_fiber_pool* root_pool,
+                                     unsigned max_fibers_to_allocate)
+{
+    // Should only set limit on root pool, not children.
+    CILK_ASSERT(NULL == root_pool->parent);
+    root_pool->alloc_max = max_fibers_to_allocate;
+}
+                                   
+void cilk_fiber_pool_destroy(cilk_fiber_pool* pool)
+{
+    CILK_ASSERT(cilk_fiber_pool_sanity_check(pool, "pool_destroy"));
+
+    // Lock my own pool, if I need to.
+    if (pool->lock) {
+        spin_mutex_lock(pool->lock);
+    }
+
+    // Give any remaining fibers to parent pool.
+    if (pool->parent) {
+        cilk_fiber_pool_move_fibers_to_parent_pool(pool, 0);
+    }
+
+    // Unlock pool.
+    if (pool->lock) {
+        spin_mutex_unlock(pool->lock);
+    }
+
+    // If I have any left in my pool, just free them myself.
+    // This method may acquire the pool lock.
+    cilk_fiber_pool_free_fibers_from_pool(pool, 0, NULL);
+
+    // Destroy the lock if there is one.
+    if (pool->lock) {
+        spin_mutex_destroy(pool->lock);
+    }
+    __cilkrts_free(pool->fibers);
+}
+
+
+cilk_fiber* cilk_fiber_allocate(cilk_fiber_pool* pool)
+{
+    CILK_ASSERT(cilk_fiber_pool_sanity_check(pool, "allocate"));
+    return cilk_fiber::allocate(pool);
+}
+
+cilk_fiber* cilk_fiber_allocate_from_heap(size_t stack_size)
+{
+    return cilk_fiber::allocate_from_heap(stack_size);
+}
+
+void cilk_fiber_reset_state(cilk_fiber* fiber, cilk_fiber_proc start_proc) 
+{
+    fiber->reset_state(start_proc);
+}
+
+int cilk_fiber_remove_reference(cilk_fiber *fiber, cilk_fiber_pool *pool)
+{
+    return fiber->remove_reference(pool);
+}
+
+cilk_fiber* cilk_fiber_allocate_from_thread()
+{
+    return cilk_fiber::allocate_from_thread();
+}
+
+int cilk_fiber_deallocate_from_thread(cilk_fiber *fiber)
+{
+    return fiber->deallocate_from_thread();
+}
+
+int cilk_fiber_remove_reference_from_thread(cilk_fiber *fiber)
+{
+    return fiber->remove_reference_from_thread();
+}
+
+int cilk_fiber_is_allocated_from_thread(cilk_fiber *fiber)
+{
+    return fiber->is_allocated_from_thread();
+}
+
+#if SUPPORT_GET_CURRENT_FIBER
+cilk_fiber* cilk_fiber_get_current_fiber(void)
+{
+    return cilk_fiber::get_current_fiber();
+}
+#endif
+
+void cilk_fiber_suspend_self_and_resume_other(cilk_fiber* self,
+                                              cilk_fiber* other)
+{
+    self->suspend_self_and_resume_other(other);
+}
+
+
+void cilk_fiber::reset_state(cilk_fiber_proc start_proc)
+{
+    // Setup the fiber and return.
+    this->m_start_proc = start_proc;
+    
+    CILK_ASSERT(!this->is_resumable());
+    CILK_ASSERT(NULL == this->m_pending_remove_ref);
+    CILK_ASSERT(NULL == this->m_pending_pool);
+}
+
+NORETURN
+cilk_fiber_remove_reference_from_self_and_resume_other(cilk_fiber*      self,
+                                                       cilk_fiber_pool* self_pool,
+                                                       cilk_fiber*      other)
+{
+#if FIBER_DEBUG >= 3
+    __cilkrts_worker* w = __cilkrts_get_tls_worker();
+    fprintf(stderr, "W=%d: cilk_fiber_deactivate_self_and_resume_other: self=%p, other=%p\n",
+            w->self,
+            self, other);
+#endif
+    CILK_ASSERT(cilk_fiber_pool_sanity_check(self_pool, "remove_reference_from_self_resume_other"));
+    self->remove_reference_from_self_and_resume_other(self_pool, other);
+    
+    // We should never return here. 
+}
+
+void cilk_fiber_set_post_switch_proc(cilk_fiber *self,
+                                     cilk_fiber_proc post_switch_proc)
+{
+    self->set_post_switch_proc(post_switch_proc);
+}
+
+void cilk_fiber_invoke_tbb_stack_op(cilk_fiber* fiber,
+                                    __cilk_tbb_stack_op op)
+{
+    fiber->invoke_tbb_stack_op(op);
+}
+
+cilk_fiber_data* cilk_fiber_get_data(cilk_fiber* fiber)
+{
+    return fiber->get_data();
+
+    /// TBD: Change this code to "return (cilk_fiber_data*)fiber;"
+    //       plus a static assert, so that this function is 
+    //       more easily inlined by the compiler.
+}
+
+int cilk_fiber_is_resumable(cilk_fiber *fiber)
+{
+    return fiber->is_resumable();
+}
+
+char* cilk_fiber_get_stack_base(cilk_fiber *fiber)
+{
+    return fiber->get_stack_base();
+}
+
+
+#if defined(_WIN32) && 0 // Only works on Windows.  Disable debugging for now.
+#define DBG_STACK_OPS(_fmt, ...) __cilkrts_dbgprintf(_fmt, __VA_ARGS__)
+#else
+#define DBG_STACK_OPS(_fmt, ...)
+#endif
+
+void cilk_fiber_set_stack_op(cilk_fiber *fiber,
+                             __cilk_tbb_stack_op_thunk o)
+{
+    cilk_fiber_data *fdata = cilk_fiber_get_data(fiber);
+    DBG_STACK_OPS ("cilk_fiber_set_stack_op - cilk_fiber %p, routine: %p, data: %p\n",
+                   fiber,
+                   o.routine,
+                   o.data);
+    fdata->stack_op_routine = o.routine;
+    fdata->stack_op_data = o.data;
+}
+
+#if 0    // Debugging function
+static
+const char *NameStackOp (enum __cilk_tbb_stack_op op)
+{
+    switch(op)
+    {
+        case CILK_TBB_STACK_ORPHAN: return "CILK_TBB_STACK_ORPHAN";
+        case CILK_TBB_STACK_ADOPT: return "CILK_TBB_STACK_ADOPT";
+        case CILK_TBB_STACK_RELEASE: return "CILK_TBB_STACK_RELEASE";
+        default: return "Unknown";
+    }
+}
+#endif
+
+/*
+ * Save TBB interop information for an unbound thread.  It will get picked
+ * up when the thread is bound to the runtime.
+ */
+void cilk_fiber_tbb_interop_save_stack_op_info(__cilk_tbb_stack_op_thunk o)
+{
+    __cilk_tbb_stack_op_thunk *saved_thunk =
+        __cilkrts_get_tls_tbb_interop();
+
+    DBG_STACK_OPS("Calling save_stack_op; o.routine=%p, o.data=%p, saved_thunk=%p\n",
+                  o.routine, o.data, saved_thunk);
+
+    // If there is not already space allocated, allocate some.
+    if (NULL == saved_thunk) {
+        saved_thunk = (__cilk_tbb_stack_op_thunk*)
+            __cilkrts_malloc(sizeof(__cilk_tbb_stack_op_thunk));
+        __cilkrts_set_tls_tbb_interop(saved_thunk);
+    }
+
+    *saved_thunk = o;
+
+    DBG_STACK_OPS ("Unbound Thread %04x: tbb_interop_save_stack_op_info - saved info\n",
+                   cilkos_get_current_thread_id());
+}
+
+/*
+ * Save TBB interop information from the cilk_fiber.  It will get picked
+ * up when the thread is bound to the runtime next time.
+ */
+void cilk_fiber_tbb_interop_save_info_from_stack(cilk_fiber *fiber)
+{
+    __cilk_tbb_stack_op_thunk *saved_thunk;
+    cilk_fiber_data* fdata;
+
+    if (NULL == fiber)
+        return;
+
+    fdata = cilk_fiber_get_data(fiber);
+    // If there is no TBB interop data, just return
+    if (NULL == fdata->stack_op_routine)
+        return;
+    
+    saved_thunk = __cilkrts_get_tls_tbb_interop();
+
+    // If there is not already space allocated, allocate some.
+    if (NULL == saved_thunk) {
+        saved_thunk = (__cilk_tbb_stack_op_thunk*)
+            __cilkrts_malloc(sizeof(__cilk_tbb_stack_op_thunk));
+        __cilkrts_set_tls_tbb_interop(saved_thunk);
+    }
+
+    saved_thunk->routine = fdata->stack_op_routine;
+    saved_thunk->data = fdata->stack_op_data;
+}
+
+/*
+ * If there's TBB interop information that was saved before the thread was
+ * bound, apply it now
+ */
+void cilk_fiber_tbb_interop_use_saved_stack_op_info(cilk_fiber* fiber)
+{
+    __cilk_tbb_stack_op_thunk *saved_thunk =
+        __cilkrts_get_tls_tbb_interop();
+
+    CILK_ASSERT(fiber);
+    // If we haven't allocated a TBB interop index, we don't have any saved info
+    if (NULL == saved_thunk) {
+        DBG_STACK_OPS ("cilk_fiber %p: tbb_interop_use_saved_stack_op_info - no saved info\n",
+                       fiber);
+        return;
+    }
+
+    DBG_STACK_OPS ("cilk_fiber %p: tbb_interop_use_saved_stack_op_info - using saved info\n",
+                   fiber);
+
+     // Associate the saved info with the __cilkrts_stack
+    cilk_fiber_set_stack_op(fiber, *saved_thunk);
+    
+    // Free the saved data.  We'll save it again if needed when the code
+    // returns from the initial function
+    cilk_fiber_tbb_interop_free_stack_op_info();
+}
+
+/*
+ * Free saved TBB interop memory.  Should only be called when the thread is
+ * not bound.
+ */
+void cilk_fiber_tbb_interop_free_stack_op_info(void)
+{
+    __cilk_tbb_stack_op_thunk *saved_thunk =
+        __cilkrts_get_tls_tbb_interop();
+
+    // If we haven't allocated a TBB interop index, we don't have any saved info
+    if (NULL == saved_thunk)
+        return;
+
+    DBG_STACK_OPS ("tbb_interop_free_stack_op_info - freeing saved info\n");
+
+    // Free the memory and wipe out the TLS value
+    __cilkrts_free(saved_thunk);
+    __cilkrts_set_tls_tbb_interop(NULL);
+}
+
+
+
+#if NEED_FIBER_REF_COUNTS
+int cilk_fiber_has_references(cilk_fiber *fiber) 
+{
+    return (fiber->get_ref_count() > 0);
+}
+
+int cilk_fiber_get_ref_count(cilk_fiber *fiber)
+{
+    return fiber->get_ref_count();
+}
+
+void cilk_fiber_add_reference(cilk_fiber *fiber)
+{
+    fiber->inc_ref_count();
+}
+#endif // NEED_FIBER_REF_COUNTS
+
+
+} // End extern "C"
+
+
+cilk_fiber_sysdep* cilk_fiber::sysdep()
+{
+    return static_cast<cilk_fiber_sysdep*>(this);
+}
+
+
+cilk_fiber::cilk_fiber()
+    : m_start_proc(NULL)
+    , m_post_switch_proc(NULL)
+    , m_pending_remove_ref(NULL)
+    , m_pending_pool(NULL)
+    , m_flags(0)
+{
+    // Clear cilk_fiber_data base-class data members
+    std::memset((cilk_fiber_data*) this, 0, sizeof(cilk_fiber_data));
+
+    // cilk_fiber data members
+    init_ref_count(0);
+}
+
+cilk_fiber::cilk_fiber(std::size_t stack_size)
+{
+    *this = cilk_fiber();  // A delegating constructor would be nice here
+    this->stack_size = stack_size;
+}
+
+cilk_fiber::~cilk_fiber() 
+{
+    // Empty destructor.
+}
+
+
+char* cilk_fiber::get_stack_base()
+{
+    return this->sysdep()->get_stack_base_sysdep();
+}
+
+cilk_fiber* cilk_fiber::allocate_from_heap(std::size_t stack_size)
+{
+    // Case 1: pool is NULL. create a new fiber from the heap
+    // No need for locks here.
+    cilk_fiber_sysdep* ret =
+        (cilk_fiber_sysdep*) __cilkrts_malloc(sizeof(cilk_fiber_sysdep));
+
+    // Error condition. If we failed to allocate a fiber from the
+    // heap, we are in trouble though...
+    if (!ret)
+        return NULL;
+
+    ::new(ret) cilk_fiber_sysdep(stack_size);
+
+    CILK_ASSERT(0 == ret->m_flags);
+    CILK_ASSERT(NULL == ret->m_pending_remove_ref);
+    CILK_ASSERT(NULL == ret->m_pending_pool);
+    ret->init_ref_count(1);
+    return ret;
+}
+
+
+#if USE_FIBER_TRY_ALLOCATE_FROM_POOL
+/**
+ * Helper method: try to allocate a fiber from this pool or its
+ * ancestors without going to the OS / heap.
+ *
+ * Returns allocated pool, or NULL if no pool is found.
+ *
+ * If pool contains a suitable fiber. Return it.  Otherwise, try to
+ * recursively grab a fiber from the parent pool, if there is one.
+ *
+ * This method will not allocate a fiber from the heap.
+ *
+ * This method could be written either recursively or iteratively.
+ * It probably does not matter which one we do.
+ *
+ * @note This method is compiled, but may not be used unless the
+ * USE_FIBER_TRY_ALLOCATE_FROM_POOL switch is set.
+ */
+cilk_fiber* cilk_fiber::try_allocate_from_pool_recursive(cilk_fiber_pool* pool)
+{
+    cilk_fiber* ret = NULL;
+
+    if (pool->size > 0) {
+        // Try to get the lock.
+        if (pool->lock) {
+            // For some reason, it seems to be better to just block on the parent
+            // pool lock, instead of using a try-lock?
+#define USE_TRY_LOCK_IN_FAST_ALLOCATE 0
+#if USE_TRY_LOCK_IN_FAST_ALLOCATE
+            int got_lock = spin_mutex_trylock(pool->lock);
+            if (!got_lock) {
+                // If we fail, skip to the parent.
+                if (pool->parent) {
+                    return try_allocate_from_pool_recursive(pool->parent);
+                }
+            }
+#else
+            spin_mutex_lock(pool->lock);
+#endif
+        }
+
+        // Check in the pool if we have the lock.
+        if (pool->size > 0) {
+            ret = pool->fibers[--pool->size];
+        }
+
+        // Release the lock once we are done updating pool fields.
+        if (pool->lock) {
+            spin_mutex_unlock(pool->lock);
+        }
+    }
+
+    if ((!ret) && (pool->parent)) {
+        return try_allocate_from_pool_recursive(pool->parent);
+    }
+
+    if (ret) {
+        // When we pull a fiber out of the pool, set its reference
+        // count before we return it.
+        ret->init_ref_count(1);
+    }
+    return ret;
+}
+#endif // USE_FIBER_TRY_ALLOCATE_FROM_POOL
+
+
+cilk_fiber* cilk_fiber::allocate(cilk_fiber_pool* pool)
+{
+    // Pool should not be NULL in this method.  But I'm not going to
+    // actually assert it, because we are likely to seg fault anyway
+    // if it is.
+    // CILK_ASSERT(NULL != pool);
+
+    cilk_fiber *ret = NULL;
+
+#if USE_FIBER_TRY_ALLOCATE_FROM_POOL
+    // "Fast" path, which doesn't go to the heap or OS until checking
+    // the ancestors first.
+    ret = try_allocate_from_pool_recursive(pool);
+    if (ret)
+        return ret;
+#endif
+
+    // If we don't get anything from the "fast path", then go through
+    // a slower path to look for a fiber.
+    //
+    //  1. Lock the pool if it is shared.
+    //  2. Look in our local pool.  If we find one, release the lock
+    //     and quit searching.
+    //  3. Otherwise, check whether we can allocate from heap.
+    //  4. Release the lock if it was acquired.
+    //  5. Try to allocate from the heap, if step 3 said we could.
+    //     If we find a fiber, then quit searching.
+    //  6. If none of these steps work, just recursively try again
+    //     from the parent.
+
+    // 1. Lock the pool if it is shared.
+    if (pool->lock) {
+        spin_mutex_lock(pool->lock);
+    }
+
+    // 2. Look in local pool.
+    if (pool->size > 0) {
+        ret = pool->fibers[--pool->size];
+        if (ret) {
+            // If we found one, release the lock once we are
+            // done updating pool fields, and break out of the
+            // loop.
+            if (pool->lock) {
+                spin_mutex_unlock(pool->lock);
+            }
+
+            // When we pull a fiber out of the pool, set its reference
+            // count just in case.
+            ret->init_ref_count(1);
+            return ret;
+        }
+    }
+
+    // 3. Check whether we can allocate from the heap.
+    bool can_allocate_from_heap = false;
+    if (pool->total < pool->alloc_max) {
+        // Track that we are allocating a new fiber from the
+        // heap, originating from this pool.
+        // This increment may be undone if we happen to fail to
+        // allocate from the heap.
+        increment_pool_total(pool);
+        can_allocate_from_heap = true;
+    }
+
+    // 4. Unlock the pool, and then allocate from the heap.
+    if (pool->lock) {
+        spin_mutex_unlock(pool->lock);
+    }
+
+    // 5. Actually try to allocate from the heap / OS.
+    if (can_allocate_from_heap) {
+        ret = allocate_from_heap(pool->stack_size);
+        // If we got something from the heap, just return it.
+        if (ret) {
+            return ret;
+        }
+
+        // Otherwise, we failed in our attempt to allocate a
+        // fiber from the heap.  Grab the lock and decrement
+        // the total again.
+        if (pool->lock) {
+            spin_mutex_lock(pool->lock);
+        }
+        decrement_pool_total(pool, 1);
+        if (pool->lock) {
+            spin_mutex_unlock(pool->lock);
+        }
+    }
+
+    // 6. If we get here, then searching this pool failed.  Go search
+    // the parent instead if we have one.
+    if (pool->parent) {
+        return allocate(pool->parent);
+    }
+    
+    return ret;
+}
+
+int cilk_fiber::remove_reference(cilk_fiber_pool* pool)
+{
+    int ref_count = this->dec_ref_count();
+    if (ref_count == 0) {
+        if (pool) {
+            deallocate_self(pool);
+        }
+        else {
+            deallocate_to_heap();
+        }
+    }
+    return ref_count;
+}
+
+cilk_fiber* cilk_fiber::allocate_from_thread()
+{
+    void* retmem = __cilkrts_malloc(sizeof(cilk_fiber_sysdep));
+    CILK_ASSERT(retmem);
+    cilk_fiber_sysdep* ret = ::new(retmem) cilk_fiber_sysdep(from_thread);
+
+    // A fiber allocated from a thread begins with a reference count
+    // of 2.  The first is for being created, and the second is for
+    // being running.
+    //
+    // Suspending this fiber will decrement the count down to 1.
+    ret->init_ref_count(2);
+
+#if SUPPORT_GET_CURRENT_FIBER    
+    // We're creating the main fiber for this thread. Set this fiber as the
+    // current fiber.
+    cilkos_set_tls_cilk_fiber(ret);
+#endif
+    return ret;
+}
+
+int cilk_fiber::deallocate_from_thread()
+{
+    CILK_ASSERT(this->is_allocated_from_thread());
+#if SUPPORT_GET_CURRENT_FIBER
+    CILK_ASSERT(this == cilkos_get_tls_cilk_fiber());
+    // Reverse of "allocate_from_thread".
+    cilkos_set_tls_cilk_fiber(NULL);
+#endif
+
+    this->assert_ref_count_at_least(2);
+
+    // Suspending the fiber should conceptually decrement the ref
+    // count by 1.
+    cilk_fiber_sysdep* self = this->sysdep();
+    self->convert_fiber_back_to_thread();
+
+    // Then, freeing the fiber itself decrements the ref count again.
+    int ref_count = this->sub_from_ref_count(2);
+    if (ref_count == 0) {
+        self->~cilk_fiber_sysdep();
+        __cilkrts_free(self);
+    }
+    return ref_count;
+}
+
+int cilk_fiber::remove_reference_from_thread()
+{
+    int ref_count = dec_ref_count();
+    if (ref_count == 0) {
+        cilk_fiber_sysdep* self = this->sysdep();
+        self->~cilk_fiber_sysdep();
+        __cilkrts_free(self);
+    }
+    return ref_count;
+}
+
+
+#if SUPPORT_GET_CURRENT_FIBER
+cilk_fiber* cilk_fiber::get_current_fiber()
+{
+    return cilk_fiber_sysdep::get_current_fiber_sysdep();
+}
+#endif
+
+void cilk_fiber::do_post_switch_actions()
+{
+    if (m_post_switch_proc) 
+    {
+        cilk_fiber_proc proc = m_post_switch_proc;
+        m_post_switch_proc = NULL;
+        proc(this);
+    }
+
+    if (m_pending_remove_ref)
+    {
+        m_pending_remove_ref->remove_reference(m_pending_pool);
+
+        // Even if we don't free it, 
+        m_pending_remove_ref = NULL;
+        m_pending_pool   = NULL;
+    }
+}
+
+void cilk_fiber::suspend_self_and_resume_other(cilk_fiber* other)
+{
+#if FIBER_DEBUG >=1
+    fprintf(stderr, "suspend_self_and_resume_other: self =%p, other=%p [owner=%p, resume_sf=%p]\n",
+            this, other, other->owner, other->resume_sf);
+#endif
+
+    // Decrement my reference count (to suspend)
+    // Increment other's count (to resume)
+    // Suspended fiber should have a reference count of at least 1.  (It is not in a pool).
+    this->dec_ref_count();
+    other->inc_ref_count();
+    this->assert_ref_count_at_least(1);
+
+    // Pass along my owner.
+    other->owner = this->owner;
+    this->owner  = NULL;
+
+    // Change this fiber to resumable.
+    CILK_ASSERT(!this->is_resumable());
+    this->set_resumable(true);
+
+    // Normally, I'd assert other->is_resumable().  But this flag may
+    // be false the first time we try to "resume" a fiber.
+    cilk_fiber_sysdep* self = this->sysdep();
+    self->suspend_self_and_resume_other_sysdep(other->sysdep());
+
+    // HAVE RESUMED EXECUTION
+    // When we come back here, we should have at least two references:
+    // one for the fiber being allocated / out of a pool, and one for it being active.
+    this->assert_ref_count_at_least(2);
+}
+
+NORETURN
+cilk_fiber::remove_reference_from_self_and_resume_other(cilk_fiber_pool* self_pool,
+                                                        cilk_fiber*      other)
+{
+    // Decrement my reference count once (to suspend)
+    // Increment other's count (to resume)
+    // Suspended fiber should have a reference count of at least 1.  (It is not in a pool).
+    this->dec_ref_count();
+    other->inc_ref_count();
+
+    // Set a pending remove reference for this fiber, once we have
+    // actually switched off.
+    other->m_pending_remove_ref = this;
+    other->m_pending_pool   = self_pool;
+
+    // Pass along my owner.
+    other->owner = this->owner;
+    this->owner  = NULL;
+
+    // Since we are deallocating self, this fiber does not become
+    // resumable.
+    CILK_ASSERT(!this->is_resumable());
+
+    cilk_fiber_sysdep* self = this->sysdep();
+    self->jump_to_resume_other_sysdep(other->sysdep());
+
+    __cilkrts_bug("Deallocating fiber.  We should never come back here.");
+    std::abort();
+}
+
+
+void cilk_fiber::deallocate_to_heap()
+{
+    cilk_fiber_sysdep* self = this->sysdep();
+    self->~cilk_fiber_sysdep();
+    __cilkrts_free(self);
+}
+
+void cilk_fiber::deallocate_self(cilk_fiber_pool* pool)
+{
+    this->set_resumable(false);
+
+    CILK_ASSERT(NULL != pool);
+    CILK_ASSERT(!this->is_allocated_from_thread());
+    this->assert_ref_count_equals(0);
+    
+    // Cases: 
+    //
+    // 1. pool has space:  Add to this pool.
+    // 2. pool is full:    Give some fibers to parent, and then free
+    //                     enough to make space for the fiber we are deallocating.
+    //                     Then put the fiber back into the pool.
+    
+    const bool need_lock = pool->lock;
+    // Grab the lock for the remaining cases.
+    if (need_lock) {
+        spin_mutex_lock(pool->lock);
+    }
+
+    // Case 1: this pool has space.  Return the fiber.
+    if (pool->size < pool->max_size)
+    {
+        // Add this fiber to pool
+        pool->fibers[pool->size++] = this;
+        if (need_lock) {
+            spin_mutex_unlock(pool->lock);
+        }
+        return;
+    }
+
+    // Case 2: Pool is full.
+    //
+    // First free up some space by giving fibers to the parent.
+    if (pool->parent)
+    {
+        // Pool is full.  Move all but "num_to_keep" fibers to parent,
+        // if we can.
+        unsigned num_to_keep = pool->max_size/2 + pool->max_size/4;
+        cilk_fiber_pool_move_fibers_to_parent_pool(pool, num_to_keep);
+    }
+
+    if (need_lock) {
+        spin_mutex_unlock(pool->lock);
+    }
+
+    // Now, free a fiber to make room for the one we need to put back,
+    // and then put this fiber back.  This step may actually return
+    // fibers to the heap.
+    cilk_fiber_pool_free_fibers_from_pool(pool, pool->max_size -1, this);
+}
+
+
+// NOTE: Except for print-debug, this code is the same as in Windows. 
+void cilk_fiber::invoke_tbb_stack_op(__cilk_tbb_stack_op op)
+{
+    cilk_fiber_data *fdata = this->get_data();
+
+    if (0 == fdata->stack_op_routine)
+    {
+        if  (CILK_TBB_STACK_RELEASE != op)
+            DBG_STACK_OPS ("Wkr %p: invoke_tbb_stack_op - %s (%d) for cilk_fiber %p, fiber %p, thread id %04x - No stack op routine\n",
+                           fdata->owner, 
+                           NameStackOp(op),
+                           op,
+                           fdata,
+                           this,
+                           cilkos_get_current_thread_id());
+        return;
+    }
+
+    // Call TBB to do it's thing
+    DBG_STACK_OPS ("Wkr %p: invoke_tbb_stack_op - op %s data %p for cilk_fiber %p, fiber %p, thread id %04x\n",
+                   fdata->owner, 
+                   NameStackOp(op),
+                   fdata->stack_op_data,
+                   fdata,
+                   this, 
+                   cilkos_get_current_thread_id());
+
+    (*fdata->stack_op_routine)(op, fdata->stack_op_data);
+    if (op == CILK_TBB_STACK_RELEASE)
+    {
+        fdata->stack_op_routine = 0;
+        fdata->stack_op_data = 0;
+    }
+}
+
+
+
+#if NEED_FIBER_REF_COUNTS
+
+void cilk_fiber::atomic_inc_ref_count()
+{
+    cilkos_atomic_add(&m_outstanding_references, 1);
+}
+
+long cilk_fiber::atomic_dec_ref_count()
+{
+    return cilkos_atomic_add(&m_outstanding_references, -1);
+}
+
+long cilk_fiber::atomic_sub_from_ref_count(long v)
+{
+    return cilkos_atomic_add(&m_outstanding_references, -v);
+}
+
+#endif // NEED_FIBER_REF_COUNTS
+
+/* End cilk_fibers.cpp */
diff --git a/libcilkrts/runtime/cilk_fiber.h b/libcilkrts/runtime/cilk_fiber.h
new file mode 100644 (file)
index 0000000..2671f92
--- /dev/null
@@ -0,0 +1,882 @@
+/* cilk_fiber.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2012-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file cilk_fiber.h
+ *
+ * @brief Abstraction of a "fiber": A coprocess-like stack and auxiliary data
+ */
+
+#ifndef INCLUDED_CILK_FIBER_DOT_H
+#define INCLUDED_CILK_FIBER_DOT_H
+
+#include <cilk/common.h>
+#ifdef __cplusplus
+#   include <cstddef>
+#else
+#   include <stddef.h>
+#endif
+
+#include "bug.h"
+#include "cilk-tbb-interop.h"
+#include "spin_mutex.h"
+#include "internal/abi.h"       // Define __cilkrts_stack_frame
+
+/**
+ * @brief Debugging level for Cilk fiber code.
+ *
+ * A value of 0 means no debugging.
+ * Higher values generate more debugging output.
+ */
+#define FIBER_DEBUG 0
+
+/**
+ * @brief Flag for validating reference counts.
+ * 
+ * Set to 1 to assert that fiber reference counts are reasonable.
+ */
+#define FIBER_CHECK_REF_COUNTS 1
+
+/**
+ * @brief Flag to determine whether fibers support reference counting.
+ * We require reference counting only on Windows, for exception
+ * processing.  Unix does not need reference counting.
+ */
+#if defined(_WIN32)
+#   define NEED_FIBER_REF_COUNTS 1
+#endif
+
+/**
+ * @brief Flag to enable support for the
+ * cilk_fiber_get_current_fiber() method.
+ *
+ * I'd like this flag to be 0.  However, the cilk_fiber test depends
+ * on being able to call this method.
+ */
+#if !defined(SUPPORT_GET_CURRENT_FIBER)
+#   define SUPPORT_GET_CURRENT_FIBER 0
+#endif
+
+/**
+ * @brief Switch for enabling "fast path" check for fibers, which
+ * doesn't go to the heap or OS until checking the ancestors first.
+ *
+ * Doing this check seems to make the stress test in
+ * cilk_fiber_pool.t.cpp run faster.  But it doesn't seem to make much
+ * difference in other benchmarks, so it is disabled by default.
+ */
+#define USE_FIBER_TRY_ALLOCATE_FROM_POOL 0
+
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/// @brief Forward reference to fiber pool.
+typedef struct cilk_fiber_pool cilk_fiber_pool;
+
+/** @brief Opaque data structure representing a fiber */
+typedef struct cilk_fiber cilk_fiber;
+
+/** @brief Function pointer type for use as a fiber's "main" procedure */
+typedef void (*cilk_fiber_proc)(cilk_fiber*);
+
+/** @brief Data structure associated with each fiber. */
+typedef struct cilk_fiber_data
+{
+    __STDNS size_t          stack_size;       /**< Size of stack for fiber    */
+    __cilkrts_worker*       owner;            /**< Worker using this fiber    */
+    __cilkrts_stack_frame*  resume_sf;        /**< Stack frame to resume      */
+    __cilk_tbb_pfn_stack_op stack_op_routine; /**< Cilk/TBB interop callback  */
+    void*                   stack_op_data;    /**< Data for Cilk/TBB callback */
+    void*                   client_data;      /**< Data managed by client     */
+
+#ifdef _WIN32
+    char *initial_sp;       /**<  Initalized in fiber_stub */
+# ifdef _WIN64
+    char *steal_frame_sp;   /**< RSP for frame stealing work */
+                            // Needed for exception handling so we can
+                            // identify when about to unwind off stack
+# endif
+#endif
+
+} cilk_fiber_data;
+
+/** @brief Pool of cilk_fiber for fiber reuse
+ *
+ * Pools form a hierarchy, with each pool pointing to its parent.  When the
+ * pool undeflows, it gets a fiber from its parent.  When a pool overflows,
+ * it returns some fibers to its parent.  If the root pool underflows, it
+ * allocates and initializes a new fiber from the heap but only if the total
+ * is less than max_size; otherwise, fiber creation fails.
+ */
+struct cilk_fiber_pool
+{
+    spin_mutex*      lock;       ///< Mutual exclusion for pool operations 
+    __STDNS size_t   stack_size; ///< Size of stacks for fibers in this pool.
+    cilk_fiber_pool* parent;     ///< @brief Parent pool.
+                                 ///< If this pool is empty, get from parent 
+
+    // Describes inactive fibers stored in the pool.
+    cilk_fiber**     fibers;     ///< Array of max_size fiber pointers 
+    unsigned         max_size;   ///< Limit on number of fibers in pool 
+    unsigned         size;       ///< Number of fibers currently in the pool
+
+    // Statistics on active fibers that were allocated from this pool,
+    // but no longer in the pool.
+    int              total;      ///< @brief Fibers allocated - fiber deallocated from pool
+                                 ///< total may be negative for non-root pools.
+    int              high_water; ///< High water mark of total fibers
+    int              alloc_max;  ///< Limit on number of fibers allocated from the heap/OS
+};
+
+/** @brief Initializes a cilk_fiber_pool structure
+ *
+ * @param pool         - The address of the pool that is to be initialized
+ * @param parent       - The address of this pool's parent, or NULL for root pool
+ * @param stack_size   - Size of stacks for fibers allocated from this pool.
+ * @param buffer_size  - The maximum number of fibers that may be pooled.
+ * @param alloc_max    - Limit on # of fibers this pool can allocate from the heap.
+ * @param is_shared    - True if accessing this pool needs a lock, false otherwise.
+ */
+void cilk_fiber_pool_init(cilk_fiber_pool* pool,
+                          cilk_fiber_pool* parent,
+                          size_t           stack_size,
+                          unsigned         buffer_size,
+                          int              alloc_max,
+                          int              is_shared);
+
+/** @brief Sets the maximum number of fibers to allocate from a root pool.
+ *
+ * @param root_pool              - A root fiber pool
+ * @param max_fibers_to_allocate - The limit on # of fibers to allocate.
+ *
+ * Sets the maximum number of fibers that can be allocated from this
+ * pool and all its descendants.  This pool must be a root pool.
+ */
+void cilk_fiber_pool_set_fiber_limit(cilk_fiber_pool* root_pool,
+                                     unsigned max_fibers_to_allocate);
+
+/** @brief De-initalizes a cilk_fiber_pool
+ *
+ * @param pool - The address of the pool that is to be destroyed
+ */
+void cilk_fiber_pool_destroy(cilk_fiber_pool* pool);
+
+/** @brief Allocates a new cilk_fiber.
+ *
+ * If the specified pool is empty, this method may choose to either
+ * allocate a fiber from the heap (if pool->total < pool->alloc_max),
+ * or retrieve a fiber from the parent pool.
+ *
+ * @note If a non-null fiber is returned, @c cilk_fiber_reset_state
+ * should be called on this fiber before using it.
+ *
+ * An allocated fiber begins with a reference count of 1.
+ * This method may lock @c pool or one of its ancestors.
+ *
+ * @pre pool should not be NULL.
+ *
+ * @param pool         The fiber pool from which to retrieve a fiber.
+ * @return             An allocated fiber, or NULL if failed to allocate.
+ */
+cilk_fiber* cilk_fiber_allocate(cilk_fiber_pool* pool);
+
+/** @brief Allocate and initialize a new cilk_fiber using memory from
+ * the heap and/or OS.
+ *
+ * The allocated fiber begins with a reference count of 1.
+ *
+ * @param stack_size   The size (in bytes) to be allocated for the fiber's
+ *                     stack.
+ * @return             An initialized fiber.  This method should not return NULL
+ *                     unless some exceptional condition has occurred.
+ */
+cilk_fiber* cilk_fiber_allocate_from_heap(size_t stack_size);
+
+
+/** @brief Resets an fiber object just allocated from a pool with the
+ * specified proc.
+ *
+ * After this call, cilk_fiber_data object associated with this fiber
+ * is filled with zeros.
+ *
+ * This function can be called only on a fiber that has been allocated
+ * from a pool, but never used.
+ *
+ * @param fiber        The fiber to reset and initialize. 
+ * @param start_proc   The function to run when switching to the fiber.  If
+ *                     null, the fiber can be used with cilk_fiber_run_proc()
+ *                     but not with cilk_fiber_resume().
+ */
+void cilk_fiber_reset_state(cilk_fiber* fiber,
+                            cilk_fiber_proc start_proc);
+
+/** @brief Remove a reference from this fiber, possibly deallocating it.
+ *
+ * This fiber is deallocated only when there are no other references
+ * to it.  Deallocation happens either by returning the fiber to the
+ * specified pool, or returning it to the heap.
+ *
+ * A fiber that is currently executing should not remove the last
+ * reference to itself.
+ *
+ * When a fiber is deallocated, destructors are not called for the
+ * objects (if any) still on its stack.  The fiber's stack and fiber
+ * data is returned to the stack pool but the client fiber data is not
+ * deallocated.
+ *
+ * If the pool overflows because of a deallocation, then some fibers
+ * will be returned to the parent pool.  If the root pool overflows,
+ * then the fiber is returned to the heap.
+ *
+ * @param fiber   The Cilk fiber to remove a reference to.
+ * @param pool    The fiber pool to which the fiber should be returned.  The
+ *                caller is assumed to have exclusive access to the pool
+ *                either because there is no contention for it or because
+ *                its lock has been acquired.  If pool is NULL, any
+ *                deallocated fiber is destroyed and returned to the
+ *                heap.
+ *
+ * @return        Final reference count.  If the count is 0, the fiber was
+ *                returned to a pool or the heap.
+ */
+int cilk_fiber_remove_reference(cilk_fiber *fiber, cilk_fiber_pool *pool);
+
+/** @brief Allocates and intializes this thread's main fiber
+ *
+ * Each thread has an "implicit" main fiber that control's the
+ * thread's initial stack.  This function makes this fiber visible to
+ * the client and allocates the Cilk-specific aspects of the implicit
+ * fiber.  A call to this function must be paired with a call to
+ *   cilk_fiber_deallocate_fiber_from_thread() 
+ * or a memory leak (or worse) will result.
+ *
+ * A fiber allocated from a thread begins with a reference count of 2.
+ * One is for being allocated, and one is for being active.
+ * (A fiber created from a thread is automatically currently executing.)
+ * The matching calls above each decrement the reference count by 1.
+ *
+ * @return  A fiber for the currently executing thread.
+ */
+cilk_fiber* cilk_fiber_allocate_from_thread(void);
+
+/** @brief Remove  a fiber created from a thread,
+ * possibly deallocating it.
+ *
+ * Same as cilk_fiber_remove_reference, except that it works on fibers
+ * created via cilk_fiber_allocate_from_thread().
+ *
+ * Fibers created from a thread are never returned to a pool.
+ *
+ * @param fiber   The Cilk fiber to remove a reference from.
+ * @return        Final reference count.  If the count is 0, the fiber was
+ *                returned to the heap.
+ */
+int cilk_fiber_remove_reference_from_thread(cilk_fiber *fiber);
+
+/** @brief Deallocate a fiber created from a thread,
+ * possibly destroying it.
+ *
+ * This method decrements the reference count of the fiber by 2, and
+ * destroys the fiber struct if the reference count is 0.
+ *
+ * OS-specific cleanup for the fiber executes unconditionally with 
+ * this method.  The destruction of the actual object, however, does
+ * not occur unless the reference count is 0.
+ *
+ * @param fiber   The cilk_fiber to deallocate from a thread.
+ * @return        Final reference count.  If the count is 0, the fiber was
+ *                returned to the heap.
+ */
+int cilk_fiber_deallocate_from_thread(cilk_fiber *fiber);
+
+/** @brief Returns true if this fiber is allocated from a thread.
+ */
+int cilk_fiber_is_allocated_from_thread(cilk_fiber *fiber);
+
+
+/** @brief Suspend execution on current fiber resumes other fiber.
+ *
+ * Suspends the current fiber and transfers control to a new fiber.  Execution
+ * on the new fiber resumes from the point at which fiber suspended itself to
+ * run a different fiber.  If fiber was freshly allocated, then runs the
+ * start_proc function specified at allocation.  This function returns when
+ * another fiber resumes the self fiber.  Note that the state of the
+ * floating-point control register (i.e., the register that controls rounding
+ * mode, etc.) is valid but indeterminate on return -- different
+ * implementations will have different results.
+ *
+ * When the @c self fiber is resumed, execution proceeds as though
+ * this function call returns.
+ *
+ * This operation increments the reference count of @p other.
+ * This operation decrements the reference count of @p self.
+ *
+ * @param self               Fiber to switch from.  Must equal current fiber.
+ * @param other              Fiber to switch to.
+ */
+void cilk_fiber_suspend_self_and_resume_other(cilk_fiber* self,
+                                              cilk_fiber* other);
+
+/** @brief Removes a reference from the currently executing fiber and
+ * resumes other fiber.
+ *
+ * Removes a reference from @p self and transfer control to @p other
+ * fiber.  Execution on @p other resumes from the point at which @p
+ * other suspended itself to run a different fiber.  If @p other fiber
+ * was freshly allocated, then runs the function specified at
+ * creation.
+ *
+ *
+ * This operation increments the reference count of @p other.
+ * 
+ * This operation conceptually decrements the reference count of
+ * @p self twice, once to suspend it, and once to remove a reference to
+ * it.  Then, if the count is 0, it is returned to the specified pool
+ * or destroyed.
+ *
+ * @pre @p self is the currently executing fiber.
+ *
+ * @param self               Fiber to remove reference switch from. 
+ * @param self_pool          Pool to which the current fiber should be returned
+ * @param other              Fiber to switch to.
+ */
+NORETURN
+cilk_fiber_remove_reference_from_self_and_resume_other(cilk_fiber*      self,
+                                                       cilk_fiber_pool* self_pool,
+                                                       cilk_fiber*      other);
+
+/** @brief Set the proc method to execute immediately after a switch
+ * to this fiber.
+ *
+ * The @c post_switch_proc method executes immediately after switching
+ * away form @p self fiber to some other fiber, but before @c self
+ * gets cleaned up.
+ * 
+ * @note A fiber can have only one post_switch_proc method at a time.
+ * If this method is called multiple times before switching to the
+ * fiber, only the last proc method will execute.
+ *
+ * @param self              Fiber.
+ * @param post_switch_proc  Proc method to execute immediately after switching to this fiber.
+ */
+void cilk_fiber_set_post_switch_proc(cilk_fiber* self, cilk_fiber_proc post_switch_proc);
+
+/** @brief Invoke TBB stack op for this fiber.
+ *
+ * @param fiber Fiber to invoke stack op for.
+ * @param op    The stack op to invoke
+ */
+void cilk_fiber_invoke_tbb_stack_op(cilk_fiber* fiber, __cilk_tbb_stack_op op);
+
+/** @brief Returns the fiber data associated with the specified fiber.
+ *
+ * The returned struct is owned by the fiber and is deallocated automatically
+ * when the fiber is destroyed.  However, the client_data field is owned by
+ * the client and must be deallocated separately.  When called for a
+ * newly-allocated fiber, the returned data is zero-filled.
+ *
+ * @param fiber   The fiber for which data is being requested.
+ * @return        The fiber data for the specified fiber
+ */
+cilk_fiber_data* cilk_fiber_get_data(cilk_fiber* fiber);
+
+/** @brief Retrieve the owner field from the fiber.
+ *
+ *  This method is provided for convenience.  One can also get the
+ *  fiber data, and then get the owner field.
+ */
+__CILKRTS_INLINE
+__cilkrts_worker* cilk_fiber_get_owner(cilk_fiber* fiber)
+{
+    // TBD: We really want a static assert here, that this cast is
+    // doing the right thing.
+    cilk_fiber_data* fdata = (cilk_fiber_data*)fiber;
+    return fdata->owner;
+}
+
+/** @brief Sets the owner field of a fiber.
+ *
+ *  This method is provided for convenience.  One can also get the
+ *  fiber data, and then get the owner field.
+ */
+__CILKRTS_INLINE
+void cilk_fiber_set_owner(cilk_fiber* fiber, __cilkrts_worker* owner) 
+{
+    // TBD: We really want a static assert here, that this cast is
+    // doing the right thing.
+    cilk_fiber_data* fdata = (cilk_fiber_data*)fiber;
+    fdata->owner = owner;
+}
+    
+/** @brief Returns true if this fiber is resumable.
+ *
+ * A fiber is considered resumable when it is not currently being
+ * executed.
+ *
+ * This function is used by Windows exception code.
+ * @param fiber   The fiber to check.
+ * @return        Nonzero value if fiber is resumable.
+ */
+int cilk_fiber_is_resumable(cilk_fiber* fiber);
+
+/**
+ * @brief Returns the base of this fiber's stack.
+ *
+ * On some platforms (e.g., Windows), the fiber must have started
+ * running before we can get this information.
+ *
+ * @param fiber   The fiber to get the stack pointer from.
+ * @return        The base of the stack, or NULL if this
+ *                information is not available yet.
+ */
+char* cilk_fiber_get_stack_base(cilk_fiber* fiber);
+
+
+/****************************************************************************
+ * TBB interop functions
+ * **************************************************************************/
+/**
+ * @brief Set the TBB callback information for a stack
+ *
+ * @param fiber The fiber to set the TBB callback information for
+ * @param o     The TBB callback thunk.  Specifies the callback address and
+ *              context value.
+ */
+void cilk_fiber_set_stack_op(cilk_fiber *fiber,
+                             __cilk_tbb_stack_op_thunk o);
+                     
+/**
+ * @brief Save the TBB callback address and context value in
+ * thread-local storage.
+ *
+ * We'll use it later when the thread binds to a worker.
+ *
+ * @param o The TBB callback thunk which is to be saved.
+ */
+void cilk_fiber_tbb_interop_save_stack_op_info(__cilk_tbb_stack_op_thunk o);
+
+/**
+ * @brief Move TBB stack-op info from thread-local storage and store
+ * it into the fiber.
+ *
+ * Called when we bind a thread to the runtime.  If there is any TBB
+ * interop information in thread-local storage, bind it to the stack
+ * now.
+ *
+ * @pre \c fiber should not be NULL.
+ * @param fiber The fiber that should take over the TBB interop information.
+ */
+void cilk_fiber_tbb_interop_use_saved_stack_op_info(cilk_fiber *fiber);
+
+/**
+ * @brief Free any TBB interop information saved in thread-local storage
+ */
+void cilk_fiber_tbb_interop_free_stack_op_info(void);
+
+/**
+ * @brief Migrate any TBB interop information from a cilk_fiber to
+ * thread-local storage.
+ *
+ * Returns immediately if no TBB interop information has been
+ * associated with the stack.
+ *
+ * @param fiber The cilk_fiber who's TBB interop information should be
+ * saved in thread-local storage.
+ */
+void cilk_fiber_tbb_interop_save_info_from_stack(cilk_fiber* fiber);
+
+
+#if SUPPORT_GET_CURRENT_FIBER
+/** @brief Returns the fiber associated with the currently executing thread
+ *
+ * @note This function is currently used only for testing the Cilk
+ * runtime.
+ *
+ * @return Fiber associated with the currently executing thread or NULL if no
+ *         fiber was associated with this thread.
+ */
+cilk_fiber* cilk_fiber_get_current_fiber(void);
+#endif
+
+
+#if NEED_FIBER_REF_COUNTS 
+/** @brief Returns true if this fiber has reference count > 0.
+ * 
+ * @param fiber   The fiber to check for references.
+ * @return        Nonzero value if the fiber has references.
+ */
+int cilk_fiber_has_references(cilk_fiber *fiber);
+
+/** @brief Returns the value of the reference count.
+ *
+ * @param fiber   The fiber to check for references.
+ * @return        The value of the reference count of fiber.
+ */
+int cilk_fiber_get_ref_count(cilk_fiber *fiber);
+
+/** @brief Adds a reference to this fiber.
+ *
+ *  Increments the reference count of a current fiber.  Fibers with
+ *  nonzero reference count will not be freed or returned to a fiber
+ *  pool.
+ *
+ * @param fiber   The fiber to add a reference to.
+ */
+void cilk_fiber_add_reference(cilk_fiber *fiber);
+
+#endif // NEED_FIBER_REF_COUNTS
+
+__CILKRTS_END_EXTERN_C
+
+#ifdef __cplusplus
+// Some C++ implementation details
+
+/// Opaque declaration of a cilk_fiber_sysdep object.
+struct cilk_fiber_sysdep;
+
+/**
+ * cilk_fiber is a base-class for system-dependent fiber implementations.
+ */
+struct cilk_fiber : protected cilk_fiber_data
+{
+  protected:
+    // This is a rare acceptable use of protected inheritence and protected
+    // variable access: when the base class and derived class collaborate
+    // tightly to comprise a single component.
+
+    /// For overloading constructor of cilk_fiber. 
+    enum from_thread_t { from_thread = 1 };
+
+    // Boolean flags capturing the status of the fiber.
+    // Each one can be set independently.
+    // A default fiber is constructed with a flag value of 0.
+    static const int RESUMABLE             = 0x01;  ///< True if the fiber is in a suspended state and can be resumed.
+    static const int ALLOCATED_FROM_THREAD = 0x02;  ///< True if fiber was allocated from a thread.
+
+    cilk_fiber_proc  m_start_proc;        ///< Function to run on start up/reset
+    cilk_fiber_proc  m_post_switch_proc;  ///< Function that executes when we first switch to a new fiber from a different one.
+
+    cilk_fiber*      m_pending_remove_ref;///< Fiber to possibly delete on start up or resume
+    cilk_fiber_pool* m_pending_pool;      ///< Pool where m_pending_remove_ref should go if it is deleted.
+    unsigned         m_flags;             ///< Captures the status of this fiber. 
+
+#if NEED_FIBER_REF_COUNTS
+    volatile long    m_outstanding_references;  ///< Counts references to this fiber.
+#endif
+
+    /// Creates a fiber with NULL data.
+    cilk_fiber();
+
+    /**
+     * @brief Creates a fiber with user-specified arguments.
+     *
+     * @param stack_size   Size of stack to use for this fiber.
+     */
+    cilk_fiber(std::size_t stack_size);
+
+    /// Empty destructor.
+    ~cilk_fiber();
+
+    /**
+     * @brief Performs any actions that happen after switching from
+     * one fiber to another.
+     *
+     * These actions are:
+     *   1. Execute m_post_switch_proc on a fiber.
+     *   2. Do any pending deallocations from the previous fiber.
+     */
+    void do_post_switch_actions();
+
+    /**
+     *@brief Helper method that converts a @c cilk_fiber object into a
+     * @c cilk_fiber_sysdep object.
+     *
+     * The @c cilk_fiber_sysdep object contains the system-dependent parts
+     * of the implementation of a @\c cilk_fiber.
+     *
+     * We could have @c cilk_fiber_sysdep inherit from @c cilk_fiber and
+     * then use virtual functions.  But since a given platform only uses
+     * one definition of @c cilk_fiber_sysdep at a time, we statically
+     * cast between them.
+     */
+    inline cilk_fiber_sysdep* sysdep();
+
+    /**
+     * @brief Set resumable flag to specified state.
+     */
+    inline void set_resumable(bool state) {
+        m_flags = state ?  (m_flags | RESUMABLE) : (m_flags & (~RESUMABLE));
+    }
+
+    /**
+     *@brief Set the allocated_from_thread flag. 
+     */
+    inline void set_allocated_from_thread(bool state) {
+        m_flags = state ?  (m_flags | ALLOCATED_FROM_THREAD) : (m_flags & (~ALLOCATED_FROM_THREAD));
+    }
+
+  public:
+
+    /**
+     * @brief Allocates and initializes a new cilk_fiber, either from
+     * the specified pool or from the heap.
+     *
+     * @pre pool should not be NULL.
+     */
+    static cilk_fiber* allocate(cilk_fiber_pool* pool);
+
+    /**
+     * @brief Allocates a fiber from the heap.
+     */
+    static cilk_fiber* allocate_from_heap(size_t stack_size);
+
+    /**
+     * @brief Return a fiber to the heap.
+     */
+    void deallocate_to_heap();
+
+    /**
+     * @brief Reset the state of a fiber just allocated from a pool.
+     */
+    void reset_state(cilk_fiber_proc start_proc);
+
+    /**
+     * @brief Remove a reference from this fiber, possibly
+     * deallocating it if the reference count becomes 0.
+     *
+     * @param pool The fiber pool to which this fiber should be returned.
+     * @return     The final reference count.
+     */
+    int remove_reference(cilk_fiber_pool* pool);
+
+    /**
+     * @brief Deallocate the fiber by returning it to the pool.
+     * @pre This method should only be called if the reference count
+     * is 0.
+     *
+     * @param pool The fiber pool to return this fiber to. If NULL,
+     *   fiber is returned to the heap.
+     */
+    void deallocate_self(cilk_fiber_pool *pool);
+
+    /** @brief Allocates and intializes this thread's main fiber. */
+    static cilk_fiber* allocate_from_thread();
+
+    /** @brief Deallocate a fiber created from a thread,
+     * possibly destroying it.
+     *
+     * This method decrements the reference count of this fiber by 2,
+     * and destroys the fiber if the reference count is 0.
+     *
+     * OS-specific cleanup for the fiber executes unconditionally with for
+     * this method.  The destruction of the actual object, however, does
+     * not occur unless the reference count is 0.
+     *
+     * @return        Final reference count.  If the count is 0, the fiber was
+     *                returned to the heap.
+     */
+    int deallocate_from_thread();
+
+    /** @brief Removes a reference from this fiber.
+     *
+     * This method deallocates this fiber if the reference count
+     * becomes 0.
+     *
+     * @pre     This fiber must be allocated from a thread.
+     * @return  The final reference count of this fiber.
+     */
+    int remove_reference_from_thread();
+
+#if SUPPORT_GET_CURRENT_FIBER
+    /** @brief Get the current fiber from TLS.
+     *
+     * @note This function is only used for testing the runtime.
+     */
+    static cilk_fiber* get_current_fiber();
+#endif
+
+    /** @brief Suspend execution on current fiber resumes other fiber.
+     * 
+     * Control returns after resuming execution of the self fiber.
+     */ 
+    void suspend_self_and_resume_other(cilk_fiber* other);
+
+
+    /** @brief Removes a reference from the currently executing fiber
+     * and resumes other fiber.
+     *
+     *  This fiber may be returned to a pool or deallocated.
+     */
+    NORETURN remove_reference_from_self_and_resume_other(cilk_fiber_pool* self_pool,
+                                                         cilk_fiber*      other);
+
+    /** @brief Set the proc method to execute immediately after a switch
+     * to this fiber.
+     *
+     * @param post_switch_proc Proc method to execute immediately
+     * after switching to this fiber.
+     */
+    inline void set_post_switch_proc(cilk_fiber_proc post_switch_proc) {
+        m_post_switch_proc = post_switch_proc;
+    }
+
+    /** @brief Returns true if this fiber is resumable.
+     *
+     * A fiber is considered resumable when it is not currently being
+     * executed.
+     */
+    inline bool is_resumable(void) {
+        return (m_flags & RESUMABLE);
+    }
+    
+    /** @brief Returns true if fiber was allocated from a thread. */   
+    inline bool is_allocated_from_thread(void) {
+        return (m_flags & ALLOCATED_FROM_THREAD);
+    }
+
+    /**
+     *@brief Get the address at the base of the stack for this fiber.
+     */
+    inline char* get_stack_base();
+    
+    /** @brief Return the data for this fiber. */ 
+    cilk_fiber_data*       get_data()       { return this; }
+
+    /** @brief Return the data for this fiber. */ 
+    cilk_fiber_data const* get_data() const { return this; }
+
+    
+#if NEED_FIBER_REF_COUNTS
+    /** @brief Verifies that this fiber's reference count equals v. */
+    inline void assert_ref_count_equals(long v) {
+    #if FIBER_CHECK_REF_COUNTS
+        CILK_ASSERT(m_outstanding_references >= v);
+    #endif
+    }
+
+    /** @brief Verifies that this fiber's reference count is at least v. */
+    inline void assert_ref_count_at_least(long v) {
+    #if FIBER_CHECK_REF_COUNTS
+        CILK_ASSERT(m_outstanding_references >= v);
+    #endif
+    }
+
+    /** @brief Get reference count. */
+    inline long get_ref_count()        { return m_outstanding_references; }
+
+    /** @brief Initialize reference count.
+     *  Operation is not atomic.
+     */
+    inline void init_ref_count(long v) { m_outstanding_references = v; }
+
+    // For Windows, updates to the fiber reference count need to be
+    // atomic, because exceptions can live on a stack that we are not
+    // currently executing on.  Thus, we can update the reference
+    // count of a fiber we are not currently executing on.
+
+    /** @brief Increment reference count for this fiber [Windows]. */
+    inline void inc_ref_count()            { atomic_inc_ref_count(); }
+
+    /** @brief Decrement reference count for this fiber [Windows]. */
+    inline long dec_ref_count()            { return atomic_dec_ref_count(); }
+
+    /** @brief Subtract v from the reference count for this fiber [Windows]. */
+    inline long sub_from_ref_count(long v) { return atomic_sub_from_ref_count(v); }
+#else  // NEED_FIBER_REF_COUNTS
+
+    // Without reference counting, we have placeholder methods.
+    inline void init_ref_count(long v) { }
+
+    inline void inc_ref_count() { }
+    
+    // With no reference counting, dec_ref_count always return 0.
+    // Thus, anyone checking is always the "last" one.
+    inline long dec_ref_count() { return 0; }
+    inline long sub_from_ref_count(long v) { return 0; }
+
+    // The assert methods do nothing.
+    inline void assert_ref_count_equals(long v) { }
+    inline void assert_ref_count_at_least(long v) { }
+#endif    
+
+    /**
+     * @brief Call TBB to tell it about an "interesting" event.
+     *
+     * @param op    Value specifying the event to track.
+     */
+    void invoke_tbb_stack_op(__cilk_tbb_stack_op op);
+
+private:
+
+    /**
+     * @brief Helper method: try to allocate a fiber from this pool or
+     * its ancestors without going to the OS / heap.
+     *
+     * Returns allocated pool, or NULL if no pool is found.
+     *
+     * If pool contains a suitable fiber. Return it.  Otherwise, try to
+     * recursively grab a fiber from the parent pool, if there is one.
+     *
+     * This method will not allocate a fiber from the heap.
+     */
+    static cilk_fiber* try_allocate_from_pool_recursive(cilk_fiber_pool* pool);
+    
+    
+#if NEED_FIBER_REF_COUNTS
+    /**
+     * @brief Atomic increment of reference count. 
+     */
+    void atomic_inc_ref_count();
+
+    /**
+     * @brief Atomic decrement of reference count.
+     */
+    long atomic_dec_ref_count();
+
+    /**
+     * @brief Atomic subtract of v from reference count.
+     * @param v Value to subtract.
+     */    
+    long atomic_sub_from_ref_count(long v);
+#endif // NEED_FIBER_REF_COUNTS
+    
+};
+
+#endif // __cplusplus
+
+#endif // ! defined(INCLUDED_CILK_FIBER_DOT_H)
diff --git a/libcilkrts/runtime/cilk_malloc.c b/libcilkrts/runtime/cilk_malloc.c
new file mode 100644 (file)
index 0000000..9d02c52
--- /dev/null
@@ -0,0 +1,84 @@
+/* cilk_malloc.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#include "cilk_malloc.h"
+
+#include <stdlib.h>
+#if defined _WIN32 || defined _WIN64 || defined __linux__
+#include <malloc.h>
+#define HAS_MEMALIGN 1
+#endif
+#ifdef __VXWORKS__
+#define HAS_MEMALIGN 1
+#include <memLib.h>
+#endif
+
+#define PREFERRED_ALIGNMENT 64  /* try to keep runtime system data
+                                   structures within one cache line */
+
+void *__cilkrts_malloc(size_t size)
+{
+    /* TODO: check for out of memory */
+#ifdef _WIN32
+    return _aligned_malloc(size, PREFERRED_ALIGNMENT);
+#elif defined HAS_MEMALIGN
+    return memalign(PREFERRED_ALIGNMENT, size);
+#else
+    return malloc(size);
+#endif
+}
+
+void *__cilkrts_realloc(void *ptr, size_t size)
+{
+#ifdef _WIN32
+    return _aligned_realloc(ptr, size, PREFERRED_ALIGNMENT);
+#else
+    return realloc(ptr, size);
+#endif
+}
+
+void __cilkrts_free(void *ptr)
+{
+#ifdef _WIN32
+    _aligned_free(ptr);
+#else
+    free(ptr);
+#endif
+}
+
+/* End cilk_malloc.c */
diff --git a/libcilkrts/runtime/cilk_malloc.h b/libcilkrts/runtime/cilk_malloc.h
new file mode 100644 (file)
index 0000000..fa0fa6d
--- /dev/null
@@ -0,0 +1,90 @@
+/* cilk_malloc.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file cilk_malloc.h
+ *
+ * @brief Provides replacement memory allocation functions to allocate
+ * (and free) memory on cache line boundaries, if supported by the OS.
+ *
+ * If aligned memory functions are not provided by the OS, the calls just
+ * pass through to the standard memory allocation functions.
+ */
+
+#ifndef INCLUDED_CILK_MALLOC_DOT_H
+#define INCLUDED_CILK_MALLOC_DOT_H
+
+#include <cilk/common.h>
+#include <stddef.h>
+
+#include "rts-common.h"
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * malloc replacement function to allocate memory aligned on a cache line
+ * boundary if aligned memory allocations are supported by the OS.
+ *
+ * @param size Number of bytes to allocate.
+ *
+ * @return pointer to memory block allocated, or NULL if unsuccessful.
+ */
+COMMON_PORTABLE void *__cilkrts_malloc(size_t size);
+
+/**
+ * realloc replacement function to allocate memory aligned on a cache line
+ * boundary if aligned memory allocations are supported by the OS.
+ *
+ * @param ptr Block to be reallocated.
+ * @param size Number of bytes to allocate.
+ *
+ * @return pointer to memory block allocated, or NULL if unsuccessful.
+ */
+COMMON_PORTABLE void *__cilkrts_realloc(void *ptr, size_t size);
+
+/**
+ * free replacement function to deallocate memory aligned on a cache line
+ * boundary if aligned memory allocations are supported by the OS.
+ *
+ * @param ptr Block to be freed.
+ */
+COMMON_PORTABLE void __cilkrts_free(void *ptr);
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_CILK_MALLOC_DOT_H)
diff --git a/libcilkrts/runtime/component.h b/libcilkrts/runtime/component.h
new file mode 100644 (file)
index 0000000..64ff3e5
--- /dev/null
@@ -0,0 +1,52 @@
+/* component.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#ifndef INCLUDED_COMPONENT_DOT_H
+#define INCLUDED_COMPONENT_DOT_H
+
+#define COMPONENT_NAME "Intel® Cilk\99 Plus Runtime"
+
+#define COMPONENT_INTERNAL_NAME COMPONENT_NAME
+
+#define COMPONENT_FILENAME "CILKRTS20"
+
+#define BuildVersionString(_major, _minor, _build, _rev) #_major "," #_minor "," #_build "," #_rev
+
+#define COMPONENT_VERSION_STRING BuildVersionString (VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION)
+
+#endif // ! defined(INCLUDED_COMPONENT_DOT_H)
diff --git a/libcilkrts/runtime/config/generic/cilk-abi-vla.c b/libcilkrts/runtime/config/generic/cilk-abi-vla.c
new file mode 100644 (file)
index 0000000..98fefa1
--- /dev/null
@@ -0,0 +1,107 @@
+/* cilk-abi-vla.cpp                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+/*
+ * Implementation of Variable Length Array (VLA) ABI.
+ *
+ * The compiler calls these functions to allocate Variable Length Arrays
+ * at runtime.  The compiler must guarantee that __cilkrts_stack_free() is
+ * called to cleanup any memory allocated by __cilkrts_stack_alloc().
+ *
+ * This generic implementation always allocates the memory from the heap.
+ * Optimally, the implementation should expand the frame of the calling
+ * function if possible, since that will be faster.  See the x86 version
+ * for one possible implementation.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "internal/abi.h"
+#include "cilk-abi-vla-internal.h"
+
+#define c_cilk_ptr_from_heap  0xc2f2f00d
+#define c_cilk_ptr_from_stack 0xc3f30d0f
+
+// Allocate space for a variable length array
+CILK_ABI(__cilkrts_void_ptr)
+__cilkrts_stack_alloc(
+    __cilkrts_stack_frame *sf,
+    size_t size,
+    size_t distance_from_sp_to_alloca_area,
+    uint32_t align,     // align is always >= minimum stack alignment and
+                        // >= ptr_size as well, and must be a power of 2.
+    uint32_t needs_tag  // non-zero if the pointer being returned needs to
+                        // be tagged
+)
+{
+    // full_size will be a multiple of align, and contains
+    // enough extra space to allocate a marker.
+    size_t full_size = (size + align - 1) & ~(align - 1);
+
+    // Allocate memory from the heap.  The compiler is responsible
+    // for guaranteeing us a chance to free it before the function
+    // exits
+
+    return (void *)vla_internal_heap_alloc(sf, full_size, align);
+}
+
+// Free the space allocated for a variable length array.
+CILK_ABI(void)
+__cilkrts_stack_free(
+    __cilkrts_stack_frame *sf,
+    void *p,
+    size_t size,
+    size_t distance_from_sp_to_alloca_area,
+    uint32_t align, // same requirements as for align in allocation,
+                    // and must match alignment that was passed when
+                    // doing the allocation 
+    uint32_t known_from_stack  // non-zero if this is known to be allocated
+                               // on the stack, and therefore has no tag
+)
+{
+    // full_size will be a multiple of align, and contains
+    // enough extra space to allocate a marker if one was needed.
+    size_t full_size = (size + align - 1) & ~(align - 1);
+
+    // Just free the allocated memory to the heap since we don't know
+    // how to expand/contract the calling frame
+    vla_internal_heap_free(t, full_size);
+}
diff --git a/libcilkrts/runtime/config/generic/os-fence.h b/libcilkrts/runtime/config/generic/os-fence.h
new file mode 100644 (file)
index 0000000..841307a
--- /dev/null
@@ -0,0 +1,53 @@
+/* os.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/*
+ * void __cilkrts_fence(void)
+ *
+ * Executes an MFENCE instruction to serialize all load and store instructions
+ * that were issued prior the MFENCE instruction. This serializing operation
+ * guarantees that every load and store instruction that precedes the MFENCE
+ * instruction is globally visible before any load or store instruction that
+ * follows the MFENCE instruction. The MFENCE instruction is ordered with
+ * respect to all load and store instructions, other MFENCE instructions, any
+ * SFENCE and LFENCE instructions, and any serializing instructions (such as
+ * the CPUID instruction).
+ */
+
+COMMON_SYSDEP void __cilkrts_fence(void); ///< MFENCE instruction
+
diff --git a/libcilkrts/runtime/config/generic/os-unix-sysdep.c b/libcilkrts/runtime/config/generic/os-unix-sysdep.c
new file mode 100644 (file)
index 0000000..fda7fc4
--- /dev/null
@@ -0,0 +1,94 @@
+/* os-unix-sysdep.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************
+ *
+ * This file contains generic implementations of system-specific code for
+ * Unix-based systems
+ */
+
+#include "os.h"
+#include "sysdep.h"
+
+/*
+ * The cycle counter is used for debugging.  This funciton is only called if
+ * CILK_PROFILE is defined when the runtime is built.
+ */
+COMMON_SYSDEP unsigned long long __cilkrts_getticks(void)
+{
+#   warning "unimplemented cycle counter"
+    return 0;
+}
+
+/*
+ * A "short pause" - called from the Cilk runtime's spinloops.
+ */
+COMMON_SYSDEP void __cilkrts_short_pause(void)
+{
+#   warning __cilkrts_short_pause empty
+}
+
+/*
+ * Interlocked exchange - used to implement the Cilk runtime's spinloops
+ */
+COMMON_SYSDEP int __cilkrts_xchg(volatile int *ptr, int x)
+{
+    x = __sync_lock_test_and_set(ptr, x);
+    return x;
+}
+
+
+/*
+ * Restore the floating point state that is stored in a stack frame at each
+ * spawn.  This should be called each time a frame is resumed.
+ *
+ * Only valid for IA32 and Intel64 processors.
+ */
+void restore_x86_fp_state (__cilkrts_stack_frame *sf)
+{
+}
+
+
+/*
+ * Save the floating point state to the __cilkrts_stack_frame at each spawn.
+ *
+ * Architecture-specific - Should only be needed on IA32 and Intel64
+ * processors.
+ */
+void sysdep_save_fp_ctrl_state(__cilkrts_stack_frame *sf)
+{
+}
+
diff --git a/libcilkrts/runtime/config/x86/cilk-abi-vla.c b/libcilkrts/runtime/config/x86/cilk-abi-vla.c
new file mode 100644 (file)
index 0000000..2d38e7f
--- /dev/null
@@ -0,0 +1,422 @@
+/* cilk-abi-vla.cpp                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+/*
+ * Implementation of Variable Length Array (VLA) ABI.
+ *
+ * __cilkrts_stack_alloc() and __cilkrts_stack_free must be compiled
+ * such that ebp/rbp is used for the stack frames.  This is done by having
+ * each of them use alloca, which forces the special frame types needed on
+ * each of the ABIs.  Additionally, for some forms of stack frame, special
+ * care must be taken because the alloca space may not be at the bottom of the
+ * stack frame of the caller.  For Intel64 windows, and for some options
+ * with other ABIs, a preallocated parameter block may exist on the stack
+ * at a lower address than the alloca.  If this is the case, the parameter
+ * distance_from_sp_to_alloca_area will be non-zero, and will indicate how
+ * much pre-allocated parameter space resides in the caller's stack frame
+ * between the alloca area, and the bottom of the stack when the call to
+ * the cilkrts is made.  As such, when non-zero it also includes any space
+ * used for passing the cilkrts_stack_alloc or cilkrts_stack_free parameters.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdint.h>
+#ifdef _WIN32
+# define alloca _alloca
+# define INLINE static __inline
+# pragma warning(disable:1025)  // Don't whine about zero extending result of unary operation
+#else
+# include <alloca.h>
+# define INLINE static inline
+#endif
+
+#include "internal/abi.h"
+#include "cilk-abi-vla-internal.h"
+
+#if defined(__x86_64) || defined(_M_X64)
+INLINE void setsp(void *val)
+{
+    __asm__("movq %0, %%rsp" : : "r"(val): "rsp");
+}
+INLINE char* getsp(void)
+{
+    void *res;
+
+    __asm__("movq %%rsp, %0" : "=r"(res): : "rsp");
+    return res;
+}
+INLINE char* getbp(void)
+{
+    void *res;
+
+    __asm__("movq %%rbp, %0" : "=r"(res): : "rbp");
+    return res;
+}
+INLINE void copy_frame_down_and_move_bp(
+    char *dst,
+    char *src,
+    size_t cpy_bytes,
+    char *new_ebp
+)
+{
+    // In this version, dst is guaranteed to be lower address than src,
+    // therefore copying upwards from src into dst is safe in case
+    // there is overlap. The number of bytes is also guaranteed to be
+    // a multiple of 8, and the copy is done in 64 bit word chunks for
+    // best efficiency.
+    __asm__(
+        "movq %0, %%rdi;"
+        "movq %1, %%rsi;"
+        "movq %2, %%rcx;"
+        "shrq $3, %%rcx;"
+        "rep movsq;"
+        "movq %3, %%rbp" : 
+        :
+        "rm"(dst), "rm"(src), "rm"(cpy_bytes), "rm"(new_ebp) :
+        "rsi", "rdi", "rcx", "rbp", "memory");
+}
+INLINE void copy_frame_up_and_move_bp(
+    char *dst,
+    char *src,
+    size_t cpy_bytes,
+    char *new_ebp
+)
+{
+    // In this version, dst is guaranteed to be higher address than src,
+    // therefore copying downwards from src into dst is safe in case
+    // there is overlap. The number of bytes is also guaranteed to be
+    // a multiple of 8, and the copy is done in 64 bit word chunks for
+    // best efficiency.
+    dst += cpy_bytes - 8;
+    src += cpy_bytes - 8;
+    __asm__(
+        "movq %0, %%rdi;"
+        "movq %1, %%rsi;"
+        "movq %2, %%rcx;"
+        "shrq $3, %%rcx;"
+        "std; rep movsq; cld;"
+        "movl %3, %%rbp;" : 
+        :
+        "rm"(dst), "rm"(src), "rm"(cpy_bytes), "rm"(new_ebp) :
+        "rsi", "rdi", "rcx", "rbp", "memory");
+}
+#else
+INLINE void setsp(void *val)
+{
+    __asm__("movl %0, %%esp" : : "r"(val): "esp");
+}
+INLINE char* getsp(void)
+{
+    void *res;
+
+    __asm__("movl %%esp, %0" : "=r"(res): : "esp");
+    return res;
+}
+INLINE char* getbp(void)
+{
+    void *res;
+
+    __asm__("movl %%ebp, %0" : "=r"(res): : "ebp");
+    return res;
+}
+INLINE void copy_frame_down_and_move_bp(
+    char *dst,
+    char *src,
+    size_t cpy_bytes,
+    char *new_ebp
+)
+{
+    // In this version, dst is guaranteed to be lower address than src,
+    // therefore copying upwards from src into dst is safe in case
+    // there is overlap. The number of bytes is also guaranteed to be
+    // a multiple of 4, and the copy is done in 32 bit word chunks for
+    // best efficiency.
+    __asm__(
+        "movl %0, %%edi;"
+        "movl %1, %%esi;"
+        "movl %2, %%ecx;"
+        "shrl $2, %%ecx;"
+        "rep movsd;"
+        "movl %3, %%ebp" : 
+        :
+        "rm"(dst), "rm"(src), "rm"(cpy_bytes), "rm"(new_ebp) :
+        "esi", "edi", "ecx", "ebp", "memory");
+}
+INLINE void copy_frame_up_and_move_bp(
+    char *dst,
+    char *src,
+    size_t cpy_bytes,
+    char *new_ebp
+)
+{
+    // In this version, dst is guaranteed to be higher address than src,
+    // therefore copying downwards from src into dst is safe in case
+    // there is overlap. The number of bytes is also guaranteed to be
+    // a multiple of 4, and the copy is done in 32 bit word chunks for
+    // best efficiency.
+    dst += cpy_bytes - 4;
+    src += cpy_bytes - 4;
+    __asm__(
+        "movl %0, %%edi;"
+        "movl %1, %%esi;"
+        "movl %2, %%ecx;"
+        "shrl $2, %%ecx;"
+        "std; rep movsd; cld;"
+        "movl %3, %%ebp" : 
+        // "=D"(dst), "=S"(src), "=C"(cpy_bytes) :
+        :
+        "rm"(dst), "rm"(src), "rm"(cpy_bytes), "rm"(new_ebp) :
+        "esi", "edi", "ecx", "ebp", "memory");
+}
+#endif
+
+
+#define c_cilk_ptr_from_heap  0xc2f2f00d
+#define c_cilk_ptr_from_stack 0xc3f30d0f
+
+CILK_ABI(__cilkrts_void_ptr)
+__cilkrts_stack_alloc(
+    __cilkrts_stack_frame *sf,
+    size_t size,
+    size_t distance_from_sp_to_alloca_area,
+    uint32_t align,     // align is always >= minimum stack alignment and
+                        // >= ptr_size as well, and must be a power of 2.
+    uint32_t needs_tag  // non-zero if the pointer being returned needs to
+                        // be tagged
+)
+{
+#ifdef __INTEL_COMPILER
+    // full_size will be a multiple of align, and contains
+    // enough extra space to allocate a marker.
+    size_t full_size = (size + align - 1) & ~(align - 1);
+
+    if (needs_tag) {
+        full_size += align;
+    }
+
+    char *t;
+    if (sf->worker != 0 &&
+        ((sf->flags & CILK_FRAME_UNSYNCHED) != 0)) {
+        t = vla_internal_heap_alloc(sf, full_size, align);
+        if (needs_tag) {
+            t += align;
+            ((uint32_t*)t)[-1] = c_cilk_ptr_from_heap;
+        }
+        return (void *)t;
+    }
+    
+    // stack is still synced, allocate full_size from esp,
+    // and record in 32 bits immediately below the space
+    // allocated that this was space that this was
+    // allocated in the stack.
+    char *old_ebp = getbp();
+    char *old_esp = getsp();
+
+    // make top_ptr point to base of first parameter.
+    char *top_ptr = ((char *)(_AddressOfReturnAddress()) +
+                    sizeof(char *));
+    size_t param_size = 0;
+
+#if defined(__x86_64)
+    // For Intel64 linux & MACH ABI, all the parameters were passed in
+    // register, so top of the stack frame above the return address
+    // is just the size of the return address plus
+    // distance_from_sp_to_alloca_area on the chance that the alloca
+    // area isn't at the very bottom of the calling functions stack.
+#elif defined(__MACH__)
+    // For ia32 MACH, parameter size is always a mutliple of 16
+    // bytes to keep the stack 16 byte aligned.  So we need to round
+    // number of parameters up to multiple of 4.
+    param_size = 8 * sizeof(char *);
+#else
+    // For both windows Intel64 ABI, and the IA32 windows and
+    // linux ABIs, space is reserved on the stack for all these
+    // parameters.  param_size is 5 * size of a stack slot.
+    param_size = 5 * sizeof(char *);
+#endif
+
+    // now make top_ptr point above the params, or if
+    // distance_from_sp_to_alloca_area is not zero, make
+    // it point above that area.  When non-zero,
+    // distance_from_sp_to_alloca area is expected to contain
+    // the parameter space, so we only add one or the other,
+    // not both.
+    top_ptr += (distance_from_sp_to_alloca_area != 0) ?
+                   distance_from_sp_to_alloca_area : param_size;
+    
+    // t needs to end up at current value of top_ptr less full_size and less
+    // distance_from_sp_to_alloca_area and
+    // then rounded down to the alignment needed.  Then we have to bump
+    // esp down by current frame_size, so that when all is done with respect
+    // to executing the return sequence, the final value of esp will be the
+    // same value as t.
+    t = (top_ptr - full_size) - distance_from_sp_to_alloca_area;
+    intptr_t temp = (intptr_t)t;
+    temp &= ~((intptr_t)(align - 1));
+    t = (char *)temp;
+
+    // ok, the value of t is set where we need it.  Now set esp
+    // to the value of t less the current frame size.
+    // So now when we do regular return esp should be left such
+    // that it has moved down by full_size.
+    size_t cur_fm_size = (top_ptr - old_esp);
+    char *new_esp = t - cur_fm_size;
+    char *new_ebp = old_ebp - (old_esp - new_esp);
+
+    // extend the stack down by at least the difference between where
+    // I want it to be and where it currently is.  This should take care
+    // of touching any pages necessary.
+    char *foo = alloca(old_esp - new_esp);
+    setsp(foo < new_esp ? foo : new_esp);
+
+    // Now set esp exactly where I want it.
+    // setsp(new_esp);
+
+    copy_frame_down_and_move_bp(new_esp, old_esp, cur_fm_size, new_ebp);
+
+    if (needs_tag) {
+        t += align;
+        ((uint32_t*)t)[-1] = c_cilk_ptr_from_stack;
+    }
+
+    return t;
+#else // Not __INTEL_COMPILER
+    // Not supported unless we can figure out how to get the size of the frame
+    return NULL;
+#endif
+}
+
+// This frees the space allocated for a variable length array.
+CILK_ABI(void)
+__cilkrts_stack_free(
+    __cilkrts_stack_frame *sf,
+    void *p,
+    size_t size,
+    size_t distance_from_sp_to_alloca_area,
+    uint32_t align, // same requirements as for align in allocation,
+                    // and must match alignment that was passed when
+                    // doing the allocation 
+    uint32_t known_from_stack  // non-zero if this is known to be allocated
+                               // on the stack, and therefore has no tag
+)
+{
+#ifdef __INTEL_COMPILER
+    uint32_t *t = (uint32_t*)p;
+
+    // full_size will be a multiple of align, and contains
+    // enough extra space to allocate a marker if one was needed.
+    size_t full_size = (size + align - 1) & ~(align - 1);
+    if (known_from_stack == 0) {
+        // if the compiler hasn't told the run-time that this is
+        // known to be on the stack, then this pointer must have been
+        // tagged such that the run-time can tell.
+        assert(t[-1] == c_cilk_ptr_from_stack ||
+               t[-1] == c_cilk_ptr_from_heap);
+
+        known_from_stack = t[-1] == c_cilk_ptr_from_stack;
+        full_size += align;    // accounts for extra space for marker
+        t = (uint32_t *)(((char *)t) - align);
+    }
+
+    if (known_from_stack) {
+        // alloca useage forces an ebp/rbp based stack frame even though
+        // 0 and unused.
+        char *foo = alloca(0);
+        if (sf->worker == 0 || (sf->flags & CILK_FRAME_UNSYNCHED) == 0) {
+            // p was allocated from current stack frame and we
+            // are synced on current stack frame.  Return the
+            // amount of the stack that needs to be freed.
+            char *old_ebp = getbp();
+            char *old_esp = getsp();
+
+            // make top_ptr point to base of first parameter.
+            char *top_ptr = ((char *)(_AddressOfReturnAddress()) +
+                            sizeof(char *));
+            size_t param_size = 0;
+
+#if defined(__x86_64)
+            // For Intel64 linux & MACH ABI, all the parameters were passed in
+            // register, so top of the stack frame above the return address
+            // is just the size of the return address plus
+            // distance_from_sp_to_alloca_area on the chance that the alloca
+            // area isn't at the very bottom of the calling functions stack.
+#elif defined(__MACH__)
+            // For ia32 MACH, parameter size is always a mutliple of 16
+            // bytes to keep the stack 16 byte aligned.  So we need to round
+            // number of parameters up to multiple of 4.
+            param_size = 8 * sizeof(char *);
+#else
+            // For both windows Intel64 ABI, and the IA32 windows and
+            // linux ABIs, space is reserved on the stack for all these
+            // parameters.  param_size is 5 * size of a stack slot.
+            param_size = 6 * sizeof(char *);
+#endif
+
+            // now make top_ptr point above the params, or if
+            // distance_from_sp_to_alloca_area is not zero, make
+            // it point above that area.  When non-zero,
+            // distance_from_sp_to_alloca area is expected to contain
+            // the parameter space, so we only add one or the other,
+            // not both.
+            top_ptr += (distance_from_sp_to_alloca_area != 0) ?
+                           distance_from_sp_to_alloca_area : param_size;
+
+            size_t cur_fm_size = (top_ptr - old_esp);
+            char *new_esp = old_esp + full_size;
+            char *new_ebp = old_ebp + full_size;
+
+            copy_frame_up_and_move_bp(new_esp, old_esp, cur_fm_size, new_ebp);
+            setsp(new_esp);
+        }
+        else {
+            // p was allocated on stack frame, but that is
+            // no longer the current stack frame.  Need to adjust the
+            // saved esp that is somewhere in the cilk runtime so that
+            // on sync, esp will be cut back correctly.
+            vla_free_from_original_stack(sf, full_size);
+        }
+    }
+    else {
+        vla_internal_heap_free(t, full_size);
+    }
+#else // Not __INTEL_COMPILER
+    // Not supported unless we can figure out how to get the size of the frame
+#endif
+}
diff --git a/libcilkrts/runtime/config/x86/os-fence.h b/libcilkrts/runtime/config/x86/os-fence.h
new file mode 100644 (file)
index 0000000..ec704e9
--- /dev/null
@@ -0,0 +1,72 @@
+/* os.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/* gcc before 4.4 does not implement __sync_synchronize properly */
+#if (__ICC >= 1110 && !(__MIC__ || __MIC2__))                      \
+    || (!defined __ICC && __GNUC__ * 10 + __GNUC_MINOR__ > 43)
+#   define HAVE_SYNC_INTRINSICS 1
+#endif
+
+
+/*
+ * void __cilkrts_fence(void)
+ *
+ * Executes an MFENCE instruction to serialize all load and store instructions
+ * that were issued prior the MFENCE instruction. This serializing operation
+ * guarantees that every load and store instruction that precedes the MFENCE
+ * instruction is globally visible before any load or store instruction that
+ * follows the MFENCE instruction. The MFENCE instruction is ordered with
+ * respect to all load and store instructions, other MFENCE instructions, any
+ * SFENCE and LFENCE instructions, and any serializing instructions (such as
+ * the CPUID instruction).
+ */
+#ifdef HAVE_SYNC_INTRINSICS
+#   define __cilkrts_fence() __sync_synchronize()
+#elif defined __ICC || defined __GNUC__
+    /* mfence is a strict subset of lock add but takes longer on many
+     * processors. */
+// #   define __cilkrts_fence() __asm__ volatile ("mfence")
+    /* On MIC, fence seems to be completely unnecessary.
+     * Just for simplicity of 1st implementation, it defaults to x86 */ 
+#   define __cilkrts_fence() __asm__ volatile ("lock addl $0,(%rsp)")
+// #elif defined _WIN32
+// #   pragma intrinsic(_ReadWriteBarrier)
+// #   define __cilkrts_fence() _ReadWriteBarrier()
+#else
+COMMON_SYSDEP void __cilkrts_fence(void); ///< MFENCE instruction
+#endif
diff --git a/libcilkrts/runtime/config/x86/os-unix-sysdep.c b/libcilkrts/runtime/config/x86/os-unix-sysdep.c
new file mode 100644 (file)
index 0000000..881bc3f
--- /dev/null
@@ -0,0 +1,123 @@
+/* os-unix-sysdep.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************
+ *
+ * This file contains system-specific code for Unix systems
+ */
+
+#include "os.h"
+#include "sysdep.h"
+#include <internal/abi.h>
+
+// On x86 processors (but not MIC processors), the compiler generated code to
+// save the FP state (rounding mode and the like) before calling setjmp.  We
+// will need to restore that state when we resume.
+#ifndef __MIC__
+# if defined(__i386__) || defined(__x86_64)
+#   define RESTORE_X86_FP_STATE
+# endif // defined(__i386__) || defined(__x86_64)
+#endif  // __MIC__
+
+/* timer support */
+COMMON_SYSDEP unsigned long long __cilkrts_getticks(void)
+{
+#if defined __i386__ || defined __x86_64
+    unsigned a, d; 
+    __asm__ volatile("rdtsc" : "=a" (a), "=d" (d)); 
+    return ((unsigned long long)a) | (((unsigned long long)d) << 32); 
+#else
+#   warning "unimplemented cycle counter"
+    return 0;
+#endif
+}
+
+COMMON_SYSDEP void __cilkrts_short_pause(void)
+{
+#if __ICC >= 1110
+#   if __MIC__ || __MIC2__
+    _mm_delay_32(16); // stall for 16 cycles
+#   else
+    _mm_pause();
+#   endif
+#elif defined __i386__ || defined __x86_64
+    __asm__("pause");
+#else
+#   warning __cilkrts_short_pause empty
+#endif
+}
+
+COMMON_SYSDEP int __cilkrts_xchg(volatile int *ptr, int x)
+{
+#if defined __i386__ || defined __x86_64
+    /* asm statement here works around icc bugs */
+    __asm__("xchgl %0,%a1" :"=r" (x) : "r" (ptr), "0" (x) :"memory");
+#else
+    x = __sync_lock_test_and_set(ptr, x);
+#endif
+    return x;
+}
+
+
+/*
+ * Restore the floating point state that is stored in a stack frame at each
+ * spawn.  This should be called each time a frame is resumed.
+ *
+ * Only valid for IA32 and Intel64 processors.
+ */
+void restore_x86_fp_state (__cilkrts_stack_frame *sf) {
+#ifdef RESTORE_X86_FP_STATE
+    __asm__ ( "ldmxcsr %0\n\t"
+              "fnclex\n\t"
+              "fldcw %1"
+              :
+              : "m" (sf->mxcsr), "m" (sf->fpcsr));
+#endif
+}
+
+
+void sysdep_save_fp_ctrl_state(__cilkrts_stack_frame *sf)
+{
+// If we're not going to restore, don't bother saving it
+#ifdef RESTORE_X86_FP_STATE
+    if (CILK_FRAME_VERSION_VALUE(sf->flags) >= 1)
+    {
+        __asm__ ("stmxcsr %0" : "=m" (sf->mxcsr));
+        __asm__ ("fnstsw %0" : "=m" (sf->fpcsr));
+    }
+#endif
+}
+
diff --git a/libcilkrts/runtime/doxygen-layout.xml b/libcilkrts/runtime/doxygen-layout.xml
new file mode 100644 (file)
index 0000000..fabe0ab
--- /dev/null
@@ -0,0 +1,222 @@
+<doxygenlayout version="1.0">
+
+<!--
+#  @copyright
+#  Copyright (C) 2011-2013, Intel Corporation
+#  All rights reserved.
+#  
+#  @copyright
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions
+#  are met:
+#  
+#    * Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#    * Neither the name of Intel Corporation nor the names of its
+#      contributors may be used to endorse or promote products derived
+#      from this software without specific prior written permission.
+#  
+#  @copyright
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+#  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+#  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+#  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+#  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+-->
+
+  <!-- Navigation index tabs for HTML output -->
+  <navindex>
+    <tab type="mainpage" visible="yes" title=""/>
+    <tab type="pages" visible="yes" title="" intro=""/>
+    <tab type="modules" visible="yes" title="" intro=""/>
+    <tab type="namespaces" visible="yes" title="">
+      <tab type="namespaces" visible="yes" title="" intro=""/>
+      <tab type="namespacemembers" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="classes" visible="yes" title="Classes, Structs and Unions">
+      <tab type="classes" visible="yes" title="Classes, Structs and Unions" intro=""/>
+      <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> 
+      <tab type="hierarchy" visible="yes" title="" intro=""/>
+      <tab type="classmembers" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="files" visible="yes" title="">
+      <tab type="files" visible="yes" title="" intro=""/>
+      <tab type="globals" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="globals" visible="yes" title="Global Functions" intro=""/>
+    <tab type="dirs" visible="yes" title="" intro=""/>
+    <tab type="examples" visible="yes" title="" intro=""/>  
+  </navindex>
+
+  <!-- Layout definition for a class page -->
+  <class>
+    <briefdescription visible="yes"/>
+    <includes visible="$SHOW_INCLUDE_FILES"/>
+    <inheritancegraph visible="$CLASS_GRAPH"/>
+    <collaborationgraph visible="$COLLABORATION_GRAPH"/>
+    <allmemberslink visible="yes"/>
+    <memberdecl>
+      <nestedclasses visible="yes" title=""/>
+      <publictypes title=""/>
+      <publicslots title=""/>
+      <signals title=""/>
+      <publicmethods title=""/>
+      <publicstaticmethods title=""/>
+      <publicattributes title=""/>
+      <publicstaticattributes title=""/>
+      <protectedtypes title=""/>
+      <protectedslots title=""/>
+      <protectedmethods title=""/>
+      <protectedstaticmethods title=""/>
+      <protectedattributes title=""/>
+      <protectedstaticattributes title=""/>
+      <packagetypes title=""/>
+      <packagemethods title=""/>
+      <packagestaticmethods title=""/>
+      <packageattributes title=""/>
+      <packagestaticattributes title=""/>
+      <properties title=""/>
+      <events title=""/>
+      <privatetypes title=""/>
+      <privateslots title=""/>
+      <privatemethods title=""/>
+      <privatestaticmethods title=""/>
+      <privateattributes title=""/>
+      <privatestaticattributes title=""/>
+      <friends title=""/>
+      <related title="" subtitle=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+    <memberdef>
+      <typedefs title=""/>
+      <enums title=""/>
+      <constructors title=""/>
+      <functions title=""/>
+      <related title=""/>
+      <variables title=""/>
+      <properties title=""/>
+      <events title=""/>
+    </memberdef>
+    <usedfiles visible="$SHOW_USED_FILES"/>
+    <authorsection visible="yes"/>
+  </class>
+
+  <!-- Layout definition for a namespace page -->
+  <namespace>
+    <briefdescription visible="yes"/>
+    <memberdecl>
+      <nestednamespaces visible="yes" title=""/>
+      <classes visible="yes" title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+    <memberdef>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdef>
+    <authorsection visible="yes"/>
+  </namespace>
+
+  <!-- Layout definition for a file page -->
+  <file>
+    <briefdescription visible="no"/>
+    <includegraph visible="$INCLUDE_GRAPH"/>
+    <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
+      <detaileddescription title="Description"/>
+      <includes visible="no"/>
+      <sourcelink visible="yes"/>
+      <memberdecl>
+      <classes visible="yes" title="Structures and Classes"/>
+      <namespaces visible="yes" title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <memberdef>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdef>
+    <authorsection/>
+  </file>
+
+  <!-- Layout definition for a group page -->
+  <group>
+    <briefdescription visible="yes"/>
+    <groupgraph visible="$GROUP_GRAPHS"/>
+    <memberdecl>
+      <classes visible="yes" title=""/>
+      <namespaces visible="yes" title=""/>
+      <dirs visible="yes" title=""/>
+      <nestedgroups visible="yes" title=""/>
+      <files visible="yes" title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <enumvalues title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <signals title=""/>
+      <publicslots title=""/>
+      <protectedslots title=""/>
+      <privateslots title=""/>
+      <events title=""/>
+      <properties title=""/>
+      <friends title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+    <memberdef>
+      <pagedocs/>
+      <inlineclasses title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <enumvalues title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <signals title=""/>
+      <publicslots title=""/>
+      <protectedslots title=""/>
+      <privateslots title=""/>
+      <events title=""/>
+      <properties title=""/>
+      <friends title=""/>
+    </memberdef>
+    <authorsection visible="yes"/>
+  </group>
+
+  <!-- Layout definition for a directory page -->
+  <directory>
+    <briefdescription visible="yes"/>
+    <directorygraph visible="yes"/>
+    <memberdecl>
+      <dirs visible="yes"/>
+      <files visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+  </directory>
+</doxygenlayout>
diff --git a/libcilkrts/runtime/doxygen.cfg b/libcilkrts/runtime/doxygen.cfg
new file mode 100644 (file)
index 0000000..684dcb5
--- /dev/null
@@ -0,0 +1,1774 @@
+# Doxyfile 1.7.4\r
+\r
+#  @copyright
+#  Copyright (C) 2011-2013, Intel Corporation
+#  All rights reserved.
+#  
+#  @copyright
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions
+#  are met:
+#  
+#    * Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#    * Neither the name of Intel Corporation nor the names of its
+#      contributors may be used to endorse or promote products derived
+#      from this software without specific prior written permission.
+#  
+#  @copyright
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+#  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+#  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+#  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+#  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+\r
+# This file describes the settings to be used by the documentation system\r
+# doxygen (www.doxygen.org) for a project.\r
+#\r
+# All text after a hash (#) is considered a comment and will be ignored.\r
+# The format is:\r
+#       TAG = value [value, ...]\r
+# For lists items can also be appended using:\r
+#       TAG += value [value, ...]\r
+# Values that contain spaces should be placed between quotes (" ").\r
+\r
+#---------------------------------------------------------------------------\r
+# Project related configuration options\r
+#---------------------------------------------------------------------------\r
+\r
+# This tag specifies the encoding used for all characters in the config file\r
+# that follow. The default is UTF-8 which is also the encoding used for all\r
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the\r
+# iconv built into libc) for the transcoding. See\r
+# http://www.gnu.org/software/libiconv for the list of possible encodings.\r
+\r
+DOXYFILE_ENCODING      = UTF-8\r
+\r
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded\r
+# by quotes) that should identify the project.\r
+\r
+PROJECT_NAME           = "Intel Cilk Plus Runtime"\r
+\r
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.\r
+# This could be handy for archiving the generated documentation or\r
+# if some version control system is used.\r
+\r
+PROJECT_NUMBER         =\r
+\r
+# Using the PROJECT_BRIEF tag one can provide an optional one line description\r
+# for a project that appears at the top of each page and should give viewer\r
+# a quick idea about the purpose of the project. Keep the description short.\r
+\r
+PROJECT_BRIEF          =\r
+\r
+# With the PROJECT_LOGO tag one can specify an logo or icon that is\r
+# included in the documentation. The maximum height of the logo should not\r
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.\r
+# Doxygen will copy the logo to the output directory.\r
+\r
+PROJECT_LOGO           =\r
+\r
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)\r
+# base path where the generated documentation will be put.\r
+# If a relative path is entered, it will be relative to the location\r
+# where doxygen was started. If left blank the current directory will be used.\r
+\r
+OUTPUT_DIRECTORY       =\r
+\r
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create\r
+# 4096 sub-directories (in 2 levels) under the output directory of each output\r
+# format and will distribute the generated files over these directories.\r
+# Enabling this option can be useful when feeding doxygen a huge amount of\r
+# source files, where putting all generated files in the same directory would\r
+# otherwise cause performance problems for the file system.\r
+\r
+CREATE_SUBDIRS         = NO\r
+\r
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all\r
+# documentation generated by doxygen is written. Doxygen will use this\r
+# information to generate all constant output in the proper language.\r
+# The default language is English, other supported languages are:\r
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,\r
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,\r
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English\r
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,\r
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,\r
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.\r
+\r
+OUTPUT_LANGUAGE        = English\r
+\r
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will\r
+# include brief member descriptions after the members that are listed in\r
+# the file and class documentation (similar to JavaDoc).\r
+# Set to NO to disable this.\r
+\r
+BRIEF_MEMBER_DESC      = YES\r
+\r
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend\r
+# the brief description of a member or function before the detailed description.\r
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the\r
+# brief descriptions will be completely suppressed.\r
+\r
+REPEAT_BRIEF           = YES\r
+\r
+# This tag implements a quasi-intelligent brief description abbreviator\r
+# that is used to form the text in various listings. Each string\r
+# in this list, if found as the leading text of the brief description, will be\r
+# stripped from the text and the result after processing the whole list, is\r
+# used as the annotated text. Otherwise, the brief description is used as-is.\r
+# If left blank, the following values are used ("$name" is automatically\r
+# replaced with the name of the entity): "The $name class" "The $name widget"\r
+# "The $name file" "is" "provides" "specifies" "contains"\r
+# "represents" "a" "an" "the"\r
+\r
+ABBREVIATE_BRIEF       =\r
+\r
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then\r
+# Doxygen will generate a detailed section even if there is only a brief\r
+# description.\r
+\r
+ALWAYS_DETAILED_SEC    = NO\r
+\r
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all\r
+# inherited members of a class in the documentation of that class as if those\r
+# members were ordinary class members. Constructors, destructors and assignment\r
+# operators of the base classes will not be shown.\r
+\r
+INLINE_INHERITED_MEMB  = NO\r
+\r
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full\r
+# path before files name in the file list and in the header files. If set\r
+# to NO the shortest path that makes the file name unique will be used.\r
+\r
+FULL_PATH_NAMES        = NO\r
+\r
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag\r
+# can be used to strip a user-defined part of the path. Stripping is\r
+# only done if one of the specified strings matches the left-hand part of\r
+# the path. The tag can be used to show relative paths in the file list.\r
+# If left blank the directory from which doxygen is run is used as the\r
+# path to strip.\r
+\r
+STRIP_FROM_PATH        =\r
+\r
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of\r
+# the path mentioned in the documentation of a class, which tells\r
+# the reader which header file to include in order to use a class.\r
+# If left blank only the name of the header file containing the class\r
+# definition is used. Otherwise one should specify the include paths that\r
+# are normally passed to the compiler using the -I flag.\r
+\r
+STRIP_FROM_INC_PATH    =\r
+\r
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter\r
+# (but less readable) file names. This can be useful if your file system\r
+# doesn't support long names like on DOS, Mac, or CD-ROM.\r
+\r
+SHORT_NAMES            = NO\r
+\r
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen\r
+# will interpret the first line (until the first dot) of a JavaDoc-style\r
+# comment as the brief description. If set to NO, the JavaDoc\r
+# comments will behave just like regular Qt-style comments\r
+# (thus requiring an explicit @brief command for a brief description.)\r
+\r
+JAVADOC_AUTOBRIEF      = NO\r
+\r
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will\r
+# interpret the first line (until the first dot) of a Qt-style\r
+# comment as the brief description. If set to NO, the comments\r
+# will behave just like regular Qt-style comments (thus requiring\r
+# an explicit \brief command for a brief description.)\r
+\r
+QT_AUTOBRIEF           = NO\r
+\r
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen\r
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///\r
+# comments) as a brief description. This used to be the default behaviour.\r
+# The new default is to treat a multi-line C++ comment block as a detailed\r
+# description. Set this tag to YES if you prefer the old behaviour instead.\r
+\r
+MULTILINE_CPP_IS_BRIEF = NO\r
+\r
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented\r
+# member inherits the documentation from any documented member that it\r
+# re-implements.\r
+\r
+INHERIT_DOCS           = YES\r
+\r
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce\r
+# a new page for each member. If set to NO, the documentation of a member will\r
+# be part of the file/class/namespace that contains it.\r
+\r
+SEPARATE_MEMBER_PAGES  = NO\r
+\r
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.\r
+# Doxygen uses this value to replace tabs by spaces in code fragments.\r
+\r
+TAB_SIZE               = 8\r
+\r
+# This tag can be used to specify a number of aliases that acts\r
+# as commands in the documentation. An alias has the form "name=value".\r
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to\r
+# put the command \sideeffect (or @sideeffect) in the documentation, which\r
+# will result in a user-defined paragraph with heading "Side Effects:".\r
+# You can put \n's in the value part of an alias to insert newlines.\r
+\r
+ALIASES                =\r
+\r
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C\r
+# sources only. Doxygen will then generate output that is more tailored for C.\r
+# For instance, some of the names that are used will be different. The list\r
+# of all members will be omitted, etc.\r
+\r
+OPTIMIZE_OUTPUT_FOR_C  = NO\r
+\r
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java\r
+# sources only. Doxygen will then generate output that is more tailored for\r
+# Java. For instance, namespaces will be presented as packages, qualified\r
+# scopes will look different, etc.\r
+\r
+OPTIMIZE_OUTPUT_JAVA   = NO\r
+\r
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran\r
+# sources only. Doxygen will then generate output that is more tailored for\r
+# Fortran.\r
+\r
+OPTIMIZE_FOR_FORTRAN   = NO\r
+\r
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL\r
+# sources. Doxygen will then generate output that is tailored for\r
+# VHDL.\r
+\r
+OPTIMIZE_OUTPUT_VHDL   = NO\r
+\r
+# Doxygen selects the parser to use depending on the extension of the files it\r
+# parses. With this tag you can assign which parser to use for a given extension.\r
+# Doxygen has a built-in mapping, but you can override or extend it using this\r
+# tag. The format is ext=language, where ext is a file extension, and language\r
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,\r
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make\r
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C\r
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions\r
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.\r
+\r
+EXTENSION_MAPPING      =\r
+\r
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want\r
+# to include (a tag file for) the STL sources as input, then you should\r
+# set this tag to YES in order to let doxygen match functions declarations and\r
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.\r
+# func(std::string) {}). This also makes the inheritance and collaboration\r
+# diagrams that involve STL classes more complete and accurate.\r
+\r
+BUILTIN_STL_SUPPORT    = NO\r
+\r
+# If you use Microsoft's C++/CLI language, you should set this option to YES to\r
+# enable parsing support.\r
+\r
+CPP_CLI_SUPPORT        = NO\r
+\r
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.\r
+# Doxygen will parse them like normal C++ but will assume all classes use public\r
+# instead of private inheritance when no explicit protection keyword is present.\r
+\r
+SIP_SUPPORT            = NO\r
+\r
+# For Microsoft's IDL there are propget and propput attributes to indicate getter\r
+# and setter methods for a property. Setting this option to YES (the default)\r
+# will make doxygen replace the get and set methods by a property in the\r
+# documentation. This will only work if the methods are indeed getting or\r
+# setting a simple type. If this is not the case, or you want to show the\r
+# methods anyway, you should set this option to NO.\r
+\r
+IDL_PROPERTY_SUPPORT   = YES\r
+\r
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC\r
+# tag is set to YES, then doxygen will reuse the documentation of the first\r
+# member in the group (if any) for the other members of the group. By default\r
+# all members of a group must be documented explicitly.\r
+\r
+DISTRIBUTE_GROUP_DOC   = NO\r
+\r
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of\r
+# the same type (for instance a group of public functions) to be put as a\r
+# subgroup of that type (e.g. under the Public Functions section). Set it to\r
+# NO to prevent subgrouping. Alternatively, this can be done per class using\r
+# the \nosubgrouping command.\r
+\r
+SUBGROUPING            = YES\r
+\r
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and\r
+# unions are shown inside the group in which they are included (e.g. using\r
+# @ingroup) instead of on a separate page (for HTML and Man pages) or\r
+# section (for LaTeX and RTF).\r
+\r
+INLINE_GROUPED_CLASSES = NO\r
+\r
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum\r
+# is documented as struct, union, or enum with the name of the typedef. So\r
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct\r
+# with name TypeT. When disabled the typedef will appear as a member of a file,\r
+# namespace, or class. And the struct will be named TypeS. This can typically\r
+# be useful for C code in case the coding convention dictates that all compound\r
+# types are typedef'ed and only the typedef is referenced, never the tag name.\r
+\r
+TYPEDEF_HIDES_STRUCT   = NO\r
+\r
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to\r
+# determine which symbols to keep in memory and which to flush to disk.\r
+# When the cache is full, less often used symbols will be written to disk.\r
+# For small to medium size projects (<1000 input files) the default value is\r
+# probably good enough. For larger projects a too small cache size can cause\r
+# doxygen to be busy swapping symbols to and from disk most of the time\r
+# causing a significant performance penalty.\r
+# If the system has enough physical memory increasing the cache will improve the\r
+# performance by keeping more symbols in memory. Note that the value works on\r
+# a logarithmic scale so increasing the size by one will roughly double the\r
+# memory usage. The cache size is given by this formula:\r
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,\r
+# corresponding to a cache size of 2^16 = 65536 symbols\r
+\r
+SYMBOL_CACHE_SIZE      = 0\r
+\r
+#---------------------------------------------------------------------------\r
+# Build related configuration options\r
+#---------------------------------------------------------------------------\r
+\r
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in\r
+# documentation are documented, even if no documentation was available.\r
+# Private class members and static file members will be hidden unless\r
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES\r
+\r
+EXTRACT_ALL            = NO\r
+\r
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class\r
+# will be included in the documentation.\r
+\r
+EXTRACT_PRIVATE        = NO\r
+\r
+# If the EXTRACT_STATIC tag is set to YES all static members of a file\r
+# will be included in the documentation.\r
+\r
+EXTRACT_STATIC         = NO\r
+\r
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)\r
+# defined locally in source files will be included in the documentation.\r
+# If set to NO only classes defined in header files are included.\r
+\r
+EXTRACT_LOCAL_CLASSES  = YES\r
+\r
+# This flag is only useful for Objective-C code. When set to YES local\r
+# methods, which are defined in the implementation section but not in\r
+# the interface are included in the documentation.\r
+# If set to NO (the default) only methods in the interface are included.\r
+\r
+EXTRACT_LOCAL_METHODS  = NO\r
+\r
+# If this flag is set to YES, the members of anonymous namespaces will be\r
+# extracted and appear in the documentation as a namespace called\r
+# 'anonymous_namespace{file}', where file will be replaced with the base\r
+# name of the file that contains the anonymous namespace. By default\r
+# anonymous namespaces are hidden.\r
+\r
+EXTRACT_ANON_NSPACES   = NO\r
+\r
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all\r
+# undocumented members of documented classes, files or namespaces.\r
+# If set to NO (the default) these members will be included in the\r
+# various overviews, but no documentation section is generated.\r
+# This option has no effect if EXTRACT_ALL is enabled.\r
+\r
+HIDE_UNDOC_MEMBERS     = NO\r
+\r
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all\r
+# undocumented classes that are normally visible in the class hierarchy.\r
+# If set to NO (the default) these classes will be included in the various\r
+# overviews. This option has no effect if EXTRACT_ALL is enabled.\r
+\r
+HIDE_UNDOC_CLASSES     = NO\r
+\r
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all\r
+# friend (class|struct|union) declarations.\r
+# If set to NO (the default) these declarations will be included in the\r
+# documentation.\r
+\r
+HIDE_FRIEND_COMPOUNDS  = NO\r
+\r
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any\r
+# documentation blocks found inside the body of a function.\r
+# If set to NO (the default) these blocks will be appended to the\r
+# function's detailed documentation block.\r
+\r
+HIDE_IN_BODY_DOCS      = NO\r
+\r
+# The INTERNAL_DOCS tag determines if documentation\r
+# that is typed after a \internal command is included. If the tag is set\r
+# to NO (the default) then the documentation will be excluded.\r
+# Set it to YES to include the internal documentation.\r
+\r
+INTERNAL_DOCS          = NO\r
+\r
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate\r
+# file names in lower-case letters. If set to YES upper-case letters are also\r
+# allowed. This is useful if you have classes or files whose names only differ\r
+# in case and if your file system supports case sensitive file names. Windows\r
+# and Mac users are advised to set this option to NO.\r
+\r
+CASE_SENSE_NAMES       = NO\r
+\r
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen\r
+# will show members with their full class and namespace scopes in the\r
+# documentation. If set to YES the scope will be hidden.\r
+\r
+HIDE_SCOPE_NAMES       = NO\r
+\r
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen\r
+# will put a list of the files that are included by a file in the documentation\r
+# of that file.\r
+\r
+SHOW_INCLUDE_FILES     = YES\r
+\r
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen\r
+# will list include files with double quotes in the documentation\r
+# rather than with sharp brackets.\r
+\r
+FORCE_LOCAL_INCLUDES   = NO\r
+\r
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]\r
+# is inserted in the documentation for inline members.\r
+\r
+INLINE_INFO            = YES\r
+\r
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen\r
+# will sort the (detailed) documentation of file and class members\r
+# alphabetically by member name. If set to NO the members will appear in\r
+# declaration order.\r
+\r
+SORT_MEMBER_DOCS       = YES\r
+\r
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the\r
+# brief documentation of file, namespace and class members alphabetically\r
+# by member name. If set to NO (the default) the members will appear in\r
+# declaration order.\r
+\r
+SORT_BRIEF_DOCS        = NO\r
+\r
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen\r
+# will sort the (brief and detailed) documentation of class members so that\r
+# constructors and destructors are listed first. If set to NO (the default)\r
+# the constructors will appear in the respective orders defined by\r
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.\r
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO\r
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.\r
+\r
+SORT_MEMBERS_CTORS_1ST = NO\r
+\r
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the\r
+# hierarchy of group names into alphabetical order. If set to NO (the default)\r
+# the group names will appear in their defined order.\r
+\r
+SORT_GROUP_NAMES       = YES\r
+\r
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be\r
+# sorted by fully-qualified names, including namespaces. If set to\r
+# NO (the default), the class list will be sorted only by class name,\r
+# not including the namespace part.\r
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.\r
+# Note: This option applies only to the class list, not to the\r
+# alphabetical list.\r
+\r
+SORT_BY_SCOPE_NAME     = NO\r
+\r
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to\r
+# do proper type resolution of all parameters of a function it will reject a\r
+# match between the prototype and the implementation of a member function even\r
+# if there is only one candidate or it is obvious which candidate to choose\r
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen\r
+# will still accept a match between prototype and implementation in such cases.\r
+\r
+STRICT_PROTO_MATCHING  = NO\r
+\r
+# The GENERATE_TODOLIST tag can be used to enable (YES) or\r
+# disable (NO) the todo list. This list is created by putting \todo\r
+# commands in the documentation.\r
+\r
+GENERATE_TODOLIST      = YES\r
+\r
+# The GENERATE_TESTLIST tag can be used to enable (YES) or\r
+# disable (NO) the test list. This list is created by putting \test\r
+# commands in the documentation.\r
+\r
+GENERATE_TESTLIST      = YES\r
+\r
+# The GENERATE_BUGLIST tag can be used to enable (YES) or\r
+# disable (NO) the bug list. This list is created by putting \bug\r
+# commands in the documentation.\r
+\r
+GENERATE_BUGLIST       = YES\r
+\r
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or\r
+# disable (NO) the deprecated list. This list is created by putting\r
+# \deprecated commands in the documentation.\r
+\r
+GENERATE_DEPRECATEDLIST= YES\r
+\r
+# The ENABLED_SECTIONS tag can be used to enable conditional\r
+# documentation sections, marked by \if sectionname ... \endif.\r
+\r
+ENABLED_SECTIONS       =\r
+\r
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines\r
+# the initial value of a variable or macro consists of for it to appear in\r
+# the documentation. If the initializer consists of more lines than specified\r
+# here it will be hidden. Use a value of 0 to hide initializers completely.\r
+# The appearance of the initializer of individual variables and macros in the\r
+# documentation can be controlled using \showinitializer or \hideinitializer\r
+# command in the documentation regardless of this setting.\r
+\r
+MAX_INITIALIZER_LINES  = 30\r
+\r
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated\r
+# at the bottom of the documentation of classes and structs. If set to YES the\r
+# list will mention the files that were used to generate the documentation.\r
+\r
+SHOW_USED_FILES        = YES\r
+\r
+# If the sources in your project are distributed over multiple directories\r
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy\r
+# in the documentation. The default is NO.\r
+\r
+SHOW_DIRECTORIES       = NO\r
+\r
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.\r
+# This will remove the Files entry from the Quick Index and from the\r
+# Folder Tree View (if specified). The default is YES.\r
+\r
+SHOW_FILES             = YES\r
+\r
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the\r
+# Namespaces page.\r
+# This will remove the Namespaces entry from the Quick Index\r
+# and from the Folder Tree View (if specified). The default is YES.\r
+\r
+SHOW_NAMESPACES        = YES\r
+\r
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that\r
+# doxygen should invoke to get the current version for each file (typically from\r
+# the version control system). Doxygen will invoke the program by executing (via\r
+# popen()) the command <command> <input-file>, where <command> is the value of\r
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file\r
+# provided by doxygen. Whatever the program writes to standard output\r
+# is used as the file version. See the manual for examples.\r
+\r
+FILE_VERSION_FILTER    =\r
+\r
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed\r
+# by doxygen. The layout file controls the global structure of the generated\r
+# output files in an output format independent way. The create the layout file\r
+# that represents doxygen's defaults, run doxygen with the -l option.\r
+# You can optionally specify a file name after the option, if omitted\r
+# DoxygenLayout.xml will be used as the name of the layout file.\r
+\r
+LAYOUT_FILE            = doxygen-layout.xml\r
+\r
+#---------------------------------------------------------------------------\r
+# configuration options related to warning and progress messages\r
+#---------------------------------------------------------------------------\r
+\r
+# The QUIET tag can be used to turn on/off the messages that are generated\r
+# by doxygen. Possible values are YES and NO. If left blank NO is used.\r
+\r
+QUIET                  = NO\r
+\r
+# The WARNINGS tag can be used to turn on/off the warning messages that are\r
+# generated by doxygen. Possible values are YES and NO. If left blank\r
+# NO is used.\r
+\r
+WARNINGS               = YES\r
+\r
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings\r
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will\r
+# automatically be disabled.\r
+\r
+WARN_IF_UNDOCUMENTED   = YES\r
+\r
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for\r
+# potential errors in the documentation, such as not documenting some\r
+# parameters in a documented function, or documenting parameters that\r
+# don't exist or using markup commands wrongly.\r
+\r
+WARN_IF_DOC_ERROR      = YES\r
+\r
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for\r
+# functions that are documented, but have no documentation for their parameters\r
+# or return value. If set to NO (the default) doxygen will only warn about\r
+# wrong or incomplete parameter documentation, but not about the absence of\r
+# documentation.\r
+\r
+WARN_NO_PARAMDOC       = NO\r
+\r
+# The WARN_FORMAT tag determines the format of the warning messages that\r
+# doxygen can produce. The string should contain the $file, $line, and $text\r
+# tags, which will be replaced by the file and line number from which the\r
+# warning originated and the warning text. Optionally the format may contain\r
+# $version, which will be replaced by the version of the file (if it could\r
+# be obtained via FILE_VERSION_FILTER)\r
+\r
+WARN_FORMAT            = "$file:$line: $text"\r
+\r
+# The WARN_LOGFILE tag can be used to specify a file to which warning\r
+# and error messages should be written. If left blank the output is written\r
+# to stderr.\r
+\r
+WARN_LOGFILE           =\r
+\r
+#---------------------------------------------------------------------------\r
+# configuration options related to the input files\r
+#---------------------------------------------------------------------------\r
+\r
+# The INPUT tag can be used to specify the files and/or directories that contain\r
+# documented source files. You may enter file names like "myfile.cpp" or\r
+# directories like "/usr/src/myproject". Separate the files or directories\r
+# with spaces.\r
+\r
+INPUT                  = ./ \\r
+                         ../include/internal/abi.h \\r
+                         ../include/cilk/cilk_api.h \\r
+                         ../include/cilk/common.h \\r
+                         ./readme.dox\r
+                         \r
+\r
+# This tag can be used to specify the character encoding of the source files\r
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is\r
+# also the default input encoding. Doxygen uses libiconv (or the iconv built\r
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for\r
+# the list of possible encodings.\r
+\r
+INPUT_ENCODING         = UTF-8\r
+\r
+# If the value of the INPUT tag contains directories, you can use the\r
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp\r
+# and *.h) to filter out the source-files in the directories. If left\r
+# blank the following patterns are tested:\r
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh\r
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py\r
+# *.f90 *.f *.for *.vhd *.vhdl\r
+\r
+FILE_PATTERNS          =\r
+\r
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories\r
+# should be searched for input files as well. Possible values are YES and NO.\r
+# If left blank NO is used.\r
+\r
+RECURSIVE              = NO\r
+\r
+# The EXCLUDE tag can be used to specify files and/or directories that should\r
+# excluded from the INPUT source files. This way you can easily exclude a\r
+# subdirectory from a directory tree whose root is specified with the INPUT tag.\r
+\r
+EXCLUDE                = attributes.h \\r
+                         cilk-ittnotify.h \\r
+                         component.h \\r
+                         rts-common.h \\r
+                         windows-clean.h\r
+\r
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or\r
+# directories that are symbolic links (a Unix file system feature) are excluded\r
+# from the input.\r
+\r
+EXCLUDE_SYMLINKS       = NO\r
+\r
+# If the value of the INPUT tag contains directories, you can use the\r
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude\r
+# certain files from those directories. Note that the wildcards are matched\r
+# against the file with absolute path, so to exclude all test directories\r
+# for example use the pattern */test/*\r
+\r
+EXCLUDE_PATTERNS       =\r
+\r
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names\r
+# (namespaces, classes, functions, etc.) that should be excluded from the\r
+# output. The symbol name can be a fully qualified name, a word, or if the\r
+# wildcard * is used, a substring. Examples: ANamespace, AClass,\r
+# AClass::ANamespace, ANamespace::*Test\r
+\r
+EXCLUDE_SYMBOLS        = _UNWIND_INFO \\r
+                         _UNWIND_CODE \\r
+                         _DISPATCHER_CONTEXT \\r
+                         __cilkrts_stack \\r
+                         pending_exception_info\r
+\r
+# The EXAMPLE_PATH tag can be used to specify one or more files or\r
+# directories that contain example code fragments that are included (see\r
+# the \include command).\r
+\r
+EXAMPLE_PATH           =\r
+\r
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the\r
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp\r
+# and *.h) to filter out the source-files in the directories. If left\r
+# blank all files are included.\r
+\r
+EXAMPLE_PATTERNS       =\r
+\r
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be\r
+# searched for input files to be used with the \include or \dontinclude\r
+# commands irrespective of the value of the RECURSIVE tag.\r
+# Possible values are YES and NO. If left blank NO is used.\r
+\r
+EXAMPLE_RECURSIVE      = NO\r
+\r
+# The IMAGE_PATH tag can be used to specify one or more files or\r
+# directories that contain image that are included in the documentation (see\r
+# the \image command).\r
+\r
+IMAGE_PATH             =\r
+\r
+# The INPUT_FILTER tag can be used to specify a program that doxygen should\r
+# invoke to filter for each input file. Doxygen will invoke the filter program\r
+# by executing (via popen()) the command <filter> <input-file>, where <filter>\r
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an\r
+# input file. Doxygen will then use the output that the filter program writes\r
+# to standard output.\r
+# If FILTER_PATTERNS is specified, this tag will be\r
+# ignored.\r
+\r
+INPUT_FILTER           =\r
+\r
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern\r
+# basis.\r
+# Doxygen will compare the file name with each pattern and apply the\r
+# filter if there is a match.\r
+# The filters are a list of the form:\r
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further\r
+# info on how filters are used. If FILTER_PATTERNS is empty or if\r
+# non of the patterns match the file name, INPUT_FILTER is applied.\r
+\r
+FILTER_PATTERNS        =\r
+\r
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using\r
+# INPUT_FILTER) will be used to filter the input files when producing source\r
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).\r
+\r
+FILTER_SOURCE_FILES    = NO\r
+\r
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file\r
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)\r
+# and it is also possible to disable source filtering for a specific pattern\r
+# using *.ext= (so without naming a filter). This option only has effect when\r
+# FILTER_SOURCE_FILES is enabled.\r
+\r
+FILTER_SOURCE_PATTERNS =\r
+\r
+#---------------------------------------------------------------------------\r
+# configuration options related to source browsing\r
+#---------------------------------------------------------------------------\r
+\r
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will\r
+# be generated. Documented entities will be cross-referenced with these sources.\r
+# Note: To get rid of all source code in the generated output, make sure also\r
+# VERBATIM_HEADERS is set to NO.\r
+\r
+SOURCE_BROWSER         = NO\r
+\r
+# Setting the INLINE_SOURCES tag to YES will include the body\r
+# of functions and classes directly in the documentation.\r
+\r
+INLINE_SOURCES         = NO\r
+\r
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct\r
+# doxygen to hide any special comment blocks from generated source code\r
+# fragments. Normal C and C++ comments will always remain visible.\r
+\r
+STRIP_CODE_COMMENTS    = YES\r
+\r
+# If the REFERENCED_BY_RELATION tag is set to YES\r
+# then for each documented function all documented\r
+# functions referencing it will be listed.\r
+\r
+REFERENCED_BY_RELATION = NO\r
+\r
+# If the REFERENCES_RELATION tag is set to YES\r
+# then for each documented function all documented entities\r
+# called/used by that function will be listed.\r
+\r
+REFERENCES_RELATION    = NO\r
+\r
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)\r
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from\r
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will\r
+# link to the source code.\r
+# Otherwise they will link to the documentation.\r
+\r
+REFERENCES_LINK_SOURCE = YES\r
+\r
+# If the USE_HTAGS tag is set to YES then the references to source code\r
+# will point to the HTML generated by the htags(1) tool instead of doxygen\r
+# built-in source browser. The htags tool is part of GNU's global source\r
+# tagging system (see http://www.gnu.org/software/global/global.html). You\r
+# will need version 4.8.6 or higher.\r
+\r
+USE_HTAGS              = NO\r
+\r
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen\r
+# will generate a verbatim copy of the header file for each class for\r
+# which an include is specified. Set to NO to disable this.\r
+\r
+VERBATIM_HEADERS       = YES\r
+\r
+#---------------------------------------------------------------------------\r
+# configuration options related to the alphabetical class index\r
+#---------------------------------------------------------------------------\r
+\r
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index\r
+# of all compounds will be generated. Enable this if the project\r
+# contains a lot of classes, structs, unions or interfaces.\r
+\r
+ALPHABETICAL_INDEX     = YES\r
+\r
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then\r
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns\r
+# in which this list will be split (can be a number in the range [1..20])\r
+\r
+COLS_IN_ALPHA_INDEX    = 5\r
+\r
+# In case all classes in a project start with a common prefix, all\r
+# classes will be put under the same header in the alphabetical index.\r
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that\r
+# should be ignored while generating the index headers.\r
+\r
+IGNORE_PREFIX          =\r
+\r
+#---------------------------------------------------------------------------\r
+# configuration options related to the HTML output\r
+#---------------------------------------------------------------------------\r
+\r
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will\r
+# generate HTML output.\r
+\r
+GENERATE_HTML          = YES\r
+\r
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.\r
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be\r
+# put in front of it. If left blank `html' will be used as the default path.\r
+\r
+HTML_OUTPUT            = html\r
+\r
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for\r
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank\r
+# doxygen will generate files with .html extension.\r
+\r
+HTML_FILE_EXTENSION    = .html\r
+\r
+# The HTML_HEADER tag can be used to specify a personal HTML header for\r
+# each generated HTML page. If it is left blank doxygen will generate a\r
+# standard header. Note that when using a custom header you are responsible\r
+# for the proper inclusion of any scripts and style sheets that doxygen\r
+# needs, which is dependent on the configuration options used.\r
+# It is adviced to generate a default header using "doxygen -w html\r
+# header.html footer.html stylesheet.css YourConfigFile" and then modify\r
+# that header. Note that the header is subject to change so you typically\r
+# have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW!\r
+\r
+HTML_HEADER            =\r
+\r
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for\r
+# each generated HTML page. If it is left blank doxygen will generate a\r
+# standard footer.\r
+\r
+HTML_FOOTER            =\r
+\r
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading\r
+# style sheet that is used by each HTML page. It can be used to\r
+# fine-tune the look of the HTML output. If the tag is left blank doxygen\r
+# will generate a default style sheet. Note that doxygen will try to copy\r
+# the style sheet file to the HTML output directory, so don't put your own\r
+# stylesheet in the HTML output directory as well, or it will be erased!\r
+\r
+HTML_STYLESHEET        =\r
+\r
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or\r
+# other source files which should be copied to the HTML output directory. Note\r
+# that these files will be copied to the base HTML output directory. Use the\r
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these\r
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that\r
+# the files will be copied as-is; there are no commands or markers available.\r
+\r
+HTML_EXTRA_FILES       =\r
+\r
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.\r
+# Doxygen will adjust the colors in the stylesheet and background images\r
+# according to this color. Hue is specified as an angle on a colorwheel,\r
+# see http://en.wikipedia.org/wiki/Hue for more information.\r
+# For instance the value 0 represents red, 60 is yellow, 120 is green,\r
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.\r
+# The allowed range is 0 to 359.\r
+\r
+HTML_COLORSTYLE_HUE    = 220\r
+\r
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of\r
+# the colors in the HTML output. For a value of 0 the output will use\r
+# grayscales only. A value of 255 will produce the most vivid colors.\r
+\r
+HTML_COLORSTYLE_SAT    = 100\r
+\r
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to\r
+# the luminance component of the colors in the HTML output. Values below\r
+# 100 gradually make the output lighter, whereas values above 100 make\r
+# the output darker. The value divided by 100 is the actual gamma applied,\r
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,\r
+# and 100 does not change the gamma.\r
+\r
+HTML_COLORSTYLE_GAMMA  = 80\r
+\r
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML\r
+# page will contain the date and time when the page was generated. Setting\r
+# this to NO can help when comparing the output of multiple runs.\r
+\r
+HTML_TIMESTAMP         = YES\r
+\r
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,\r
+# files or namespaces will be aligned in HTML using tables. If set to\r
+# NO a bullet list will be used.\r
+\r
+HTML_ALIGN_MEMBERS     = YES\r
+\r
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML\r
+# documentation will contain sections that can be hidden and shown after the\r
+# page has loaded. For this to work a browser that supports\r
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox\r
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).\r
+\r
+HTML_DYNAMIC_SECTIONS  = NO\r
+\r
+# If the GENERATE_DOCSET tag is set to YES, additional index files\r
+# will be generated that can be used as input for Apple's Xcode 3\r
+# integrated development environment, introduced with OSX 10.5 (Leopard).\r
+# To create a documentation set, doxygen will generate a Makefile in the\r
+# HTML output directory. Running make will produce the docset in that\r
+# directory and running "make install" will install the docset in\r
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find\r
+# it at startup.\r
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html\r
+# for more information.\r
+\r
+GENERATE_DOCSET        = NO\r
+\r
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the\r
+# feed. A documentation feed provides an umbrella under which multiple\r
+# documentation sets from a single provider (such as a company or product suite)\r
+# can be grouped.\r
+\r
+DOCSET_FEEDNAME        = "Doxygen generated docs"\r
+\r
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that\r
+# should uniquely identify the documentation set bundle. This should be a\r
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen\r
+# will append .docset to the name.\r
+\r
+DOCSET_BUNDLE_ID       = com.Intel.CilkPlusRuntime\r
+\r
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify\r
+# the documentation publisher. This should be a reverse domain-name style\r
+# string, e.g. com.mycompany.MyDocSet.documentation.\r
+\r
+DOCSET_PUBLISHER_ID    = com.Intel.CilkPlusRuntime\r
+\r
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.\r
+\r
+DOCSET_PUBLISHER_NAME  = "Intel Corporation"\r
+\r
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files\r
+# will be generated that can be used as input for tools like the\r
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)\r
+# of the generated HTML documentation.\r
+\r
+GENERATE_HTMLHELP      = NO\r
+\r
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can\r
+# be used to specify the file name of the resulting .chm file. You\r
+# can add a path in front of the file if the result should not be\r
+# written to the html output directory.\r
+\r
+CHM_FILE               =\r
+\r
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can\r
+# be used to specify the location (absolute path including file name) of\r
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run\r
+# the HTML help compiler on the generated index.hhp.\r
+\r
+HHC_LOCATION           =\r
+\r
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag\r
+# controls if a separate .chi index file is generated (YES) or that\r
+# it should be included in the master .chm file (NO).\r
+\r
+GENERATE_CHI           = NO\r
+\r
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING\r
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file\r
+# content.\r
+\r
+CHM_INDEX_ENCODING     =\r
+\r
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag\r
+# controls whether a binary table of contents is generated (YES) or a\r
+# normal table of contents (NO) in the .chm file.\r
+\r
+BINARY_TOC             = NO\r
+\r
+# The TOC_EXPAND flag can be set to YES to add extra items for group members\r
+# to the contents of the HTML help documentation and to the tree view.\r
+\r
+TOC_EXPAND             = NO\r
+\r
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and\r
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated\r
+# that can be used as input for Qt's qhelpgenerator to generate a\r
+# Qt Compressed Help (.qch) of the generated HTML documentation.\r
+\r
+GENERATE_QHP           = NO\r
+\r
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can\r
+# be used to specify the file name of the resulting .qch file.\r
+# The path specified is relative to the HTML output folder.\r
+\r
+QCH_FILE               =\r
+\r
+# The QHP_NAMESPACE tag specifies the namespace to use when generating\r
+# Qt Help Project output. For more information please see\r
+# http://doc.trolltech.com/qthelpproject.html#namespace\r
+\r
+QHP_NAMESPACE          = org.doxygen.Project\r
+\r
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating\r
+# Qt Help Project output. For more information please see\r
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders\r
+\r
+QHP_VIRTUAL_FOLDER     = doc\r
+\r
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to\r
+# add. For more information please see\r
+# http://doc.trolltech.com/qthelpproject.html#custom-filters\r
+\r
+QHP_CUST_FILTER_NAME   =\r
+\r
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the\r
+# custom filter to add. For more information please see\r
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">\r
+# Qt Help Project / Custom Filters</a>.\r
+\r
+QHP_CUST_FILTER_ATTRS  =\r
+\r
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this\r
+# project's\r
+# filter section matches.\r
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">\r
+# Qt Help Project / Filter Attributes</a>.\r
+\r
+QHP_SECT_FILTER_ATTRS  =\r
+\r
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can\r
+# be used to specify the location of Qt's qhelpgenerator.\r
+# If non-empty doxygen will try to run qhelpgenerator on the generated\r
+# .qhp file.\r
+\r
+QHG_LOCATION           =\r
+\r
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files\r
+#  will be generated, which together with the HTML files, form an Eclipse help\r
+# plugin. To install this plugin and make it available under the help contents\r
+# menu in Eclipse, the contents of the directory containing the HTML and XML\r
+# files needs to be copied into the plugins directory of eclipse. The name of\r
+# the directory within the plugins directory should be the same as\r
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before\r
+# the help appears.\r
+\r
+GENERATE_ECLIPSEHELP   = NO\r
+\r
+# A unique identifier for the eclipse help plugin. When installing the plugin\r
+# the directory name containing the HTML and XML files should also have\r
+# this name.\r
+\r
+ECLIPSE_DOC_ID         = org.doxygen.Project\r
+\r
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at\r
+# top of each HTML page. The value NO (the default) enables the index and\r
+# the value YES disables it.\r
+\r
+DISABLE_INDEX          = NO\r
+\r
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values\r
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML\r
+# documentation. Note that a value of 0 will completely suppress the enum\r
+# values from appearing in the overview section.\r
+\r
+ENUM_VALUES_PER_LINE   = 4\r
+\r
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index\r
+# structure should be generated to display hierarchical information.\r
+# If the tag value is set to YES, a side panel will be generated\r
+# containing a tree-like index structure (just like the one that\r
+# is generated for HTML Help). For this to work a browser that supports\r
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).\r
+# Windows users are probably better off using the HTML help feature.\r
+\r
+GENERATE_TREEVIEW      = NO\r
+\r
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,\r
+# and Class Hierarchy pages using a tree view instead of an ordered list.\r
+\r
+USE_INLINE_TREES       = NO\r
+\r
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be\r
+# used to set the initial width (in pixels) of the frame in which the tree\r
+# is shown.\r
+\r
+TREEVIEW_WIDTH         = 250\r
+\r
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open\r
+# links to external symbols imported via tag files in a separate window.\r
+\r
+EXT_LINKS_IN_WINDOW    = NO\r
+\r
+# Use this tag to change the font size of Latex formulas included\r
+# as images in the HTML documentation. The default is 10. Note that\r
+# when you change the font size after a successful doxygen run you need\r
+# to manually remove any form_*.png images from the HTML output directory\r
+# to force them to be regenerated.\r
+\r
+FORMULA_FONTSIZE       = 10\r
+\r
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images\r
+# generated for formulas are transparent PNGs. Transparent PNGs are\r
+# not supported properly for IE 6.0, but are supported on all modern browsers.\r
+# Note that when changing this option you need to delete any form_*.png files\r
+# in the HTML output before the changes have effect.\r
+\r
+FORMULA_TRANSPARENT    = YES\r
+\r
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax\r
+# (see http://www.mathjax.org) which uses client side Javascript for the\r
+# rendering instead of using prerendered bitmaps. Use this if you do not\r
+# have LaTeX installed or if you want to formulas look prettier in the HTML\r
+# output. When enabled you also need to install MathJax separately and\r
+# configure the path to it using the MATHJAX_RELPATH option.\r
+\r
+USE_MATHJAX            = NO\r
+\r
+# When MathJax is enabled you need to specify the location relative to the\r
+# HTML output directory using the MATHJAX_RELPATH option. The destination\r
+# directory should contain the MathJax.js script. For instance, if the mathjax\r
+# directory is located at the same level as the HTML output directory, then\r
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the\r
+# mathjax.org site, so you can quickly see the result without installing\r
+# MathJax, but it is strongly recommended to install a local copy of MathJax\r
+# before deployment.\r
+\r
+MATHJAX_RELPATH        = http://www.mathjax.org/mathjax\r
+\r
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box\r
+# for the HTML output. The underlying search engine uses javascript\r
+# and DHTML and should work on any modern browser. Note that when using\r
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets\r
+# (GENERATE_DOCSET) there is already a search function so this one should\r
+# typically be disabled. For large projects the javascript based search engine\r
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.\r
+\r
+SEARCHENGINE           = YES\r
+\r
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be\r
+# implemented using a PHP enabled web server instead of at the web client\r
+# using Javascript. Doxygen will generate the search PHP script and index\r
+# file to put on the web server. The advantage of the server\r
+# based approach is that it scales better to large projects and allows\r
+# full text search. The disadvantages are that it is more difficult to setup\r
+# and does not have live searching capabilities.\r
+\r
+SERVER_BASED_SEARCH    = NO\r
+\r
+#---------------------------------------------------------------------------\r
+# configuration options related to the LaTeX output\r
+#---------------------------------------------------------------------------\r
+\r
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will\r
+# generate Latex output.\r
+\r
+GENERATE_LATEX         = NO\r
+\r
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.\r
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be\r
+# put in front of it. If left blank `latex' will be used as the default path.\r
+\r
+LATEX_OUTPUT           = latex\r
+\r
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be\r
+# invoked. If left blank `latex' will be used as the default command name.\r
+# Note that when enabling USE_PDFLATEX this option is only used for\r
+# generating bitmaps for formulas in the HTML output, but not in the\r
+# Makefile that is written to the output directory.\r
+\r
+LATEX_CMD_NAME         = latex\r
+\r
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to\r
+# generate index for LaTeX. If left blank `makeindex' will be used as the\r
+# default command name.\r
+\r
+MAKEINDEX_CMD_NAME     = makeindex\r
+\r
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact\r
+# LaTeX documents. This may be useful for small projects and may help to\r
+# save some trees in general.\r
+\r
+COMPACT_LATEX          = NO\r
+\r
+# The PAPER_TYPE tag can be used to set the paper type that is used\r
+# by the printer. Possible values are: a4, letter, legal and\r
+# executive. If left blank a4wide will be used.\r
+\r
+PAPER_TYPE             = a4\r
+\r
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX\r
+# packages that should be included in the LaTeX output.\r
+\r
+EXTRA_PACKAGES         =\r
+\r
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for\r
+# the generated latex document. The header should contain everything until\r
+# the first chapter. If it is left blank doxygen will generate a\r
+# standard header. Notice: only use this tag if you know what you are doing!\r
+\r
+LATEX_HEADER           =\r
+\r
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for\r
+# the generated latex document. The footer should contain everything after\r
+# the last chapter. If it is left blank doxygen will generate a\r
+# standard footer. Notice: only use this tag if you know what you are doing!\r
+\r
+LATEX_FOOTER           =\r
+\r
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated\r
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will\r
+# contain links (just like the HTML output) instead of page references\r
+# This makes the output suitable for online browsing using a pdf viewer.\r
+\r
+PDF_HYPERLINKS         = YES\r
+\r
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of\r
+# plain latex in the generated Makefile. Set this option to YES to get a\r
+# higher quality PDF documentation.\r
+\r
+USE_PDFLATEX           = YES\r
+\r
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.\r
+# command to the generated LaTeX files. This will instruct LaTeX to keep\r
+# running if errors occur, instead of asking the user for help.\r
+# This option is also used when generating formulas in HTML.\r
+\r
+LATEX_BATCHMODE        = NO\r
+\r
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not\r
+# include the index chapters (such as File Index, Compound Index, etc.)\r
+# in the output.\r
+\r
+LATEX_HIDE_INDICES     = NO\r
+\r
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include\r
+# source code with syntax highlighting in the LaTeX output.\r
+# Note that which sources are shown also depends on other settings\r
+# such as SOURCE_BROWSER.\r
+\r
+LATEX_SOURCE_CODE      = NO\r
+\r
+#---------------------------------------------------------------------------\r
+# configuration options related to the RTF output\r
+#---------------------------------------------------------------------------\r
+\r
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output\r
+# The RTF output is optimized for Word 97 and may not look very pretty with\r
+# other RTF readers or editors.\r
+\r
+GENERATE_RTF           = NO\r
+\r
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.\r
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be\r
+# put in front of it. If left blank `rtf' will be used as the default path.\r
+\r
+RTF_OUTPUT             = rtf\r
+\r
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact\r
+# RTF documents. This may be useful for small projects and may help to\r
+# save some trees in general.\r
+\r
+COMPACT_RTF            = NO\r
+\r
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated\r
+# will contain hyperlink fields. The RTF file will\r
+# contain links (just like the HTML output) instead of page references.\r
+# This makes the output suitable for online browsing using WORD or other\r
+# programs which support those fields.\r
+# Note: wordpad (write) and others do not support links.\r
+\r
+RTF_HYPERLINKS         = NO\r
+\r
+# Load stylesheet definitions from file. Syntax is similar to doxygen's\r
+# config file, i.e. a series of assignments. You only have to provide\r
+# replacements, missing definitions are set to their default value.\r
+\r
+RTF_STYLESHEET_FILE    =\r
+\r
+# Set optional variables used in the generation of an rtf document.\r
+# Syntax is similar to doxygen's config file.\r
+\r
+RTF_EXTENSIONS_FILE    =\r
+\r
+#---------------------------------------------------------------------------\r
+# configuration options related to the man page output\r
+#---------------------------------------------------------------------------\r
+\r
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will\r
+# generate man pages\r
+\r
+GENERATE_MAN           = NO\r
+\r
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.\r
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be\r
+# put in front of it. If left blank `man' will be used as the default path.\r
+\r
+MAN_OUTPUT             = man\r
+\r
+# The MAN_EXTENSION tag determines the extension that is added to\r
+# the generated man pages (default is the subroutine's section .3)\r
+\r
+MAN_EXTENSION          = .3\r
+\r
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,\r
+# then it will generate one additional man file for each entity\r
+# documented in the real man page(s). These additional files\r
+# only source the real man page, but without them the man command\r
+# would be unable to find the correct page. The default is NO.\r
+\r
+MAN_LINKS              = NO\r
+\r
+#---------------------------------------------------------------------------\r
+# configuration options related to the XML output\r
+#---------------------------------------------------------------------------\r
+\r
+# If the GENERATE_XML tag is set to YES Doxygen will\r
+# generate an XML file that captures the structure of\r
+# the code including all documentation.\r
+\r
+GENERATE_XML           = NO\r
+\r
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.\r
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be\r
+# put in front of it. If left blank `xml' will be used as the default path.\r
+\r
+XML_OUTPUT             = xml\r
+\r
+# The XML_SCHEMA tag can be used to specify an XML schema,\r
+# which can be used by a validating XML parser to check the\r
+# syntax of the XML files.\r
+\r
+XML_SCHEMA             =\r
+\r
+# The XML_DTD tag can be used to specify an XML DTD,\r
+# which can be used by a validating XML parser to check the\r
+# syntax of the XML files.\r
+\r
+XML_DTD                =\r
+\r
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will\r
+# dump the program listings (including syntax highlighting\r
+# and cross-referencing information) to the XML output. Note that\r
+# enabling this will significantly increase the size of the XML output.\r
+\r
+XML_PROGRAMLISTING     = YES\r
+\r
+#---------------------------------------------------------------------------\r
+# configuration options for the AutoGen Definitions output\r
+#---------------------------------------------------------------------------\r
+\r
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will\r
+# generate an AutoGen Definitions (see autogen.sf.net) file\r
+# that captures the structure of the code including all\r
+# documentation. Note that this feature is still experimental\r
+# and incomplete at the moment.\r
+\r
+GENERATE_AUTOGEN_DEF   = NO\r
+\r
+#---------------------------------------------------------------------------\r
+# configuration options related to the Perl module output\r
+#---------------------------------------------------------------------------\r
+\r
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will\r
+# generate a Perl module file that captures the structure of\r
+# the code including all documentation. Note that this\r
+# feature is still experimental and incomplete at the\r
+# moment.\r
+\r
+GENERATE_PERLMOD       = NO\r
+\r
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate\r
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able\r
+# to generate PDF and DVI output from the Perl module output.\r
+\r
+PERLMOD_LATEX          = NO\r
+\r
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be\r
+# nicely formatted so it can be parsed by a human reader.\r
+# This is useful\r
+# if you want to understand what is going on.\r
+# On the other hand, if this\r
+# tag is set to NO the size of the Perl module output will be much smaller\r
+# and Perl will parse it just the same.\r
+\r
+PERLMOD_PRETTY         = YES\r
+\r
+# The names of the make variables in the generated doxyrules.make file\r
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.\r
+# This is useful so different doxyrules.make files included by the same\r
+# Makefile don't overwrite each other's variables.\r
+\r
+PERLMOD_MAKEVAR_PREFIX =\r
+\r
+#---------------------------------------------------------------------------\r
+# Configuration options related to the preprocessor\r
+#---------------------------------------------------------------------------\r
+\r
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will\r
+# evaluate all C-preprocessor directives found in the sources and include\r
+# files.\r
+\r
+ENABLE_PREPROCESSING   = YES\r
+\r
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro\r
+# names in the source code. If set to NO (the default) only conditional\r
+# compilation will be performed. Macro expansion can be done in a controlled\r
+# way by setting EXPAND_ONLY_PREDEF to YES.\r
+\r
+MACRO_EXPANSION        = YES\r
+\r
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES\r
+# then the macro expansion is limited to the macros specified with the\r
+# PREDEFINED and EXPAND_AS_DEFINED tags.\r
+\r
+EXPAND_ONLY_PREDEF     = YES\r
+\r
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files\r
+# pointed to by INCLUDE_PATH will be searched when a #include is found.\r
+\r
+SEARCH_INCLUDES        = YES\r
+\r
+# The INCLUDE_PATH tag can be used to specify one or more directories that\r
+# contain include files that are not input files but should be processed by\r
+# the preprocessor.\r
+\r
+INCLUDE_PATH           =\r
+\r
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard\r
+# patterns (like *.h and *.hpp) to filter out the header-files in the\r
+# directories. If left blank, the patterns specified with FILE_PATTERNS will\r
+# be used.\r
+\r
+INCLUDE_FILE_PATTERNS  =\r
+\r
+# The PREDEFINED tag can be used to specify one or more macro names that\r
+# are defined before the preprocessor is started (similar to the -D option of\r
+# gcc). The argument of the tag is a list of macros of the form: name\r
+# or name=definition (no spaces). If the definition and the = are\r
+# omitted =1 is assumed. To prevent a macro definition from being\r
+# undefined via #undef or recursively expanded use the := operator\r
+# instead of the = operator.\r
+\r
+PREDEFINED             = _WIN32 \\r
+                         COMMON_SYSDEP= \\r
+                         COMMON_PORTABLE= \\r
+                         NON_COMMON= \\r
+                         __CILKRTS_BEGIN_EXTERN_C= \\r
+                         __CILKRTS_END_EXTERN_C= \\r
+                         CILK_API(t)=t \\r
+                         CILK_ABI(t)=t \\r
+                         CILK_ABI_THROWS(t)=t \\r
+                         CALLBACK= \\r
+                         __CILKRTS_INLINE=inline \\r
+                         __CILKRTS_ABI_VERSION=1 \\r
+                         __cplusplus \\r
+\r
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then\r
+# this tag can be used to specify a list of macro names that should be expanded.\r
+# The macro definition that is found in the sources will be used.\r
+# Use the PREDEFINED tag if you want to use a different macro definition that\r
+# overrules the definition found in the source code.\r
+\r
+EXPAND_AS_DEFINED      =\r
+\r
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then\r
+# doxygen's preprocessor will remove all references to function-like macros\r
+# that are alone on a line, have an all uppercase name, and do not end with a\r
+# semicolon, because these will confuse the parser if not removed.\r
+\r
+SKIP_FUNCTION_MACROS   = YES\r
+\r
+#---------------------------------------------------------------------------\r
+# Configuration::additions related to external references\r
+#---------------------------------------------------------------------------\r
+\r
+# The TAGFILES option can be used to specify one or more tagfiles.\r
+# Optionally an initial location of the external documentation\r
+# can be added for each tagfile. The format of a tag file without\r
+# this location is as follows:\r
+#\r
+# TAGFILES = file1 file2 ...\r
+# Adding location for the tag files is done as follows:\r
+#\r
+# TAGFILES = file1=loc1 "file2 = loc2" ...\r
+# where "loc1" and "loc2" can be relative or absolute paths or\r
+# URLs. If a location is present for each tag, the installdox tool\r
+# does not have to be run to correct the links.\r
+# Note that each tag file must have a unique name\r
+# (where the name does NOT include the path)\r
+# If a tag file is not located in the directory in which doxygen\r
+# is run, you must also specify the path to the tagfile here.\r
+\r
+TAGFILES               =\r
+\r
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create\r
+# a tag file that is based on the input files it reads.\r
+\r
+GENERATE_TAGFILE       =\r
+\r
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed\r
+# in the class index. If set to NO only the inherited external classes\r
+# will be listed.\r
+\r
+ALLEXTERNALS           = NO\r
+\r
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed\r
+# in the modules index. If set to NO, only the current project's groups will\r
+# be listed.\r
+\r
+EXTERNAL_GROUPS        = YES\r
+\r
+# The PERL_PATH should be the absolute path and name of the perl script\r
+# interpreter (i.e. the result of `which perl').\r
+\r
+PERL_PATH              = /usr/bin/perl\r
+\r
+#---------------------------------------------------------------------------\r
+# Configuration options related to the dot tool\r
+#---------------------------------------------------------------------------\r
+\r
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will\r
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base\r
+# or super classes. Setting the tag to NO turns the diagrams off. Note that\r
+# this option also works with HAVE_DOT disabled, but it is recommended to\r
+# install and use dot, since it yields more powerful graphs.\r
+\r
+CLASS_DIAGRAMS         = YES\r
+\r
+# You can define message sequence charts within doxygen comments using the \msc\r
+# command. Doxygen will then run the mscgen tool (see\r
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the\r
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where\r
+# the mscgen tool resides. If left empty the tool is assumed to be found in the\r
+# default search path.\r
+\r
+MSCGEN_PATH            =\r
+\r
+# If set to YES, the inheritance and collaboration graphs will hide\r
+# inheritance and usage relations if the target is undocumented\r
+# or is not a class.\r
+\r
+HIDE_UNDOC_RELATIONS   = YES\r
+\r
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is\r
+# available from the path. This tool is part of Graphviz, a graph visualization\r
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section\r
+# have no effect if this option is set to NO (the default)\r
+\r
+HAVE_DOT               = NO\r
+\r
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is\r
+# allowed to run in parallel. When set to 0 (the default) doxygen will\r
+# base this on the number of processors available in the system. You can set it\r
+# explicitly to a value larger than 0 to get control over the balance\r
+# between CPU load and processing speed.\r
+\r
+DOT_NUM_THREADS        = 0\r
+\r
+# By default doxygen will write a font called Helvetica to the output\r
+# directory and reference it in all dot files that doxygen generates.\r
+# When you want a differently looking font you can specify the font name\r
+# using DOT_FONTNAME. You need to make sure dot is able to find the font,\r
+# which can be done by putting it in a standard location or by setting the\r
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory\r
+# containing the font.\r
+\r
+DOT_FONTNAME           = Helvetica\r
+\r
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.\r
+# The default size is 10pt.\r
+\r
+DOT_FONTSIZE           = 10\r
+\r
+# By default doxygen will tell dot to use the output directory to look for the\r
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a\r
+# different font using DOT_FONTNAME you can set the path where dot\r
+# can find it using this tag.\r
+\r
+DOT_FONTPATH           =\r
+\r
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen\r
+# will generate a graph for each documented class showing the direct and\r
+# indirect inheritance relations. Setting this tag to YES will force the\r
+# the CLASS_DIAGRAMS tag to NO.\r
+\r
+CLASS_GRAPH            = YES\r
+\r
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen\r
+# will generate a graph for each documented class showing the direct and\r
+# indirect implementation dependencies (inheritance, containment, and\r
+# class references variables) of the class with other documented classes.\r
+\r
+COLLABORATION_GRAPH    = YES\r
+\r
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen\r
+# will generate a graph for groups, showing the direct groups dependencies\r
+\r
+GROUP_GRAPHS           = YES\r
+\r
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and\r
+# collaboration diagrams in a style similar to the OMG's Unified Modeling\r
+# Language.\r
+\r
+UML_LOOK               = NO\r
+\r
+# If set to YES, the inheritance and collaboration graphs will show the\r
+# relations between templates and their instances.\r
+\r
+TEMPLATE_RELATIONS     = NO\r
+\r
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT\r
+# tags are set to YES then doxygen will generate a graph for each documented\r
+# file showing the direct and indirect include dependencies of the file with\r
+# other documented files.\r
+\r
+INCLUDE_GRAPH          = YES\r
+\r
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and\r
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each\r
+# documented header file showing the documented files that directly or\r
+# indirectly include this file.\r
+\r
+INCLUDED_BY_GRAPH      = YES\r
+\r
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then\r
+# doxygen will generate a call dependency graph for every global function\r
+# or class method. Note that enabling this option will significantly increase\r
+# the time of a run. So in most cases it will be better to enable call graphs\r
+# for selected functions only using the \callgraph command.\r
+\r
+CALL_GRAPH             = NO\r
+\r
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then\r
+# doxygen will generate a caller dependency graph for every global function\r
+# or class method. Note that enabling this option will significantly increase\r
+# the time of a run. So in most cases it will be better to enable caller\r
+# graphs for selected functions only using the \callergraph command.\r
+\r
+CALLER_GRAPH           = NO\r
+\r
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen\r
+# will generate a graphical hierarchy of all classes instead of a textual one.\r
+\r
+GRAPHICAL_HIERARCHY    = YES\r
+\r
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES\r
+# then doxygen will show the dependencies a directory has on other directories\r
+# in a graphical way. The dependency relations are determined by the #include\r
+# relations between the files in the directories.\r
+\r
+DIRECTORY_GRAPH        = YES\r
+\r
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images\r
+# generated by dot. Possible values are svg, png, jpg, or gif.\r
+# If left blank png will be used.\r
+\r
+DOT_IMAGE_FORMAT       = png\r
+\r
+# The tag DOT_PATH can be used to specify the path where the dot tool can be\r
+# found. If left blank, it is assumed the dot tool can be found in the path.\r
+\r
+DOT_PATH               =\r
+\r
+# The DOTFILE_DIRS tag can be used to specify one or more directories that\r
+# contain dot files that are included in the documentation (see the\r
+# \dotfile command).\r
+\r
+DOTFILE_DIRS           =\r
+\r
+# The MSCFILE_DIRS tag can be used to specify one or more directories that\r
+# contain msc files that are included in the documentation (see the\r
+# \mscfile command).\r
+\r
+MSCFILE_DIRS           =\r
+\r
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of\r
+# nodes that will be shown in the graph. If the number of nodes in a graph\r
+# becomes larger than this value, doxygen will truncate the graph, which is\r
+# visualized by representing a node as a red box. Note that doxygen if the\r
+# number of direct children of the root node in a graph is already larger than\r
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note\r
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.\r
+\r
+DOT_GRAPH_MAX_NODES    = 50\r
+\r
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the\r
+# graphs generated by dot. A depth value of 3 means that only nodes reachable\r
+# from the root by following a path via at most 3 edges will be shown. Nodes\r
+# that lay further from the root node will be omitted. Note that setting this\r
+# option to 1 or 2 may greatly reduce the computation time needed for large\r
+# code bases. Also note that the size of a graph can be further restricted by\r
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.\r
+\r
+MAX_DOT_GRAPH_DEPTH    = 0\r
+\r
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent\r
+# background. This is disabled by default, because dot on Windows does not\r
+# seem to support this out of the box. Warning: Depending on the platform used,\r
+# enabling this option may lead to badly anti-aliased labels on the edges of\r
+# a graph (i.e. they become hard to read).\r
+\r
+DOT_TRANSPARENT        = NO\r
+\r
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output\r
+# files in one run (i.e. multiple -o and -T options on the command line). This\r
+# makes dot run faster, but since only newer versions of dot (>1.8.10)\r
+# support this, this feature is disabled by default.\r
+\r
+DOT_MULTI_TARGETS      = NO\r
+\r
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will\r
+# generate a legend page explaining the meaning of the various boxes and\r
+# arrows in the dot generated graphs.\r
+\r
+GENERATE_LEGEND        = YES\r
+\r
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will\r
+# remove the intermediate dot files that are used to generate\r
+# the various graphs.\r
+\r
+DOT_CLEANUP            = YES\r
diff --git a/libcilkrts/runtime/except-gcc.cpp b/libcilkrts/runtime/except-gcc.cpp
new file mode 100644 (file)
index 0000000..bd08d18
--- /dev/null
@@ -0,0 +1,597 @@
+/* except-gcc.cpp                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#include "except-gcc.h"
+#include "except.h"
+#include "sysdep.h"
+#include "bug.h"
+#include "local_state.h"
+#include "full_frame.h"
+#include "scheduler.h"
+#include "frame_malloc.h"
+#include "pedigrees.h"
+
+#include <stdint.h>
+#include <typeinfo>
+
+#define DEBUG_EXCEPTIONS 0
+
+struct pending_exception_info
+{
+    void make(__cxa_eh_globals *, _Unwind_Exception *, bool);
+    void destruct();
+    bool empty() const;
+    void check() const;
+    /* Active exception at time of suspend. */
+    _Unwind_Exception *active;
+    /* If true the most recently caught exception is to be rethrown
+       on resume.  This handling is technically incorrect but allows
+       running without compiler support; the proper standards-compliant
+       method is to save the exception in the previous field. */
+    bool rethrow;
+    struct __cxa_eh_globals runtime_state;
+};
+
+void pending_exception_info::check() const
+{
+    if (active)
+        CILK_ASSERT((int)runtime_state.uncaughtExceptions > 0);
+}
+
+void pending_exception_info::make(__cxa_eh_globals *state_in,
+                                  _Unwind_Exception *exc_in, bool rethrow_in)
+{
+    active = exc_in;
+    rethrow = rethrow_in;
+    runtime_state = *state_in;
+    /* Read and clear C++ runtime state.  */
+    state_in->caughtExceptions = 0;
+    state_in->uncaughtExceptions = 0;
+#if CILK_LIB_DEBUG
+    check();
+#endif
+}
+
+bool
+pending_exception_info::empty() const
+{
+    return !active && !rethrow && !runtime_state.caughtExceptions &&
+        !runtime_state.uncaughtExceptions;
+}
+
+#if DEBUG_EXCEPTIONS
+#include <stdio.h>
+static void
+decode_exceptions(char *out, size_t len, struct pending_exception_info *info)
+{
+    if (info->empty())
+        snprintf(out, len, "[empty]");
+    else if (info->rethrow)
+        snprintf(out, len, "[rethrow %p]",
+                 info->runtime_state.caughtExceptions);
+    else
+        snprintf(out, len, "[throw %p]", (void *)info->active);
+}
+#endif
+
+static void
+save_exception_info(__cilkrts_worker *w,
+                    __cxa_eh_globals *state,
+                    _Unwind_Exception *exc,
+                    bool rethrow,
+                    const char *why)
+{
+    struct pending_exception_info *info =
+        (struct pending_exception_info *)__cilkrts_frame_malloc(w, sizeof (struct pending_exception_info));
+    CILK_ASSERT(info);
+    info->make(state, exc, rethrow);
+
+#if DEBUG_EXCEPTIONS
+    {
+        char buf[40];
+        decode_exceptions(buf, sizeof buf, info);
+        fprintf(stderr, "make exception info W%u %p %s (%s)\n",
+                w->self, info, buf, why);
+    }
+#endif
+
+    CILK_ASSERT(w->l->pending_exception == 0);
+    w->l->pending_exception = info;
+}
+
+#if DEBUG_EXCEPTIONS
+#include <stdio.h> /* DEBUG */
+
+static void decode_flags(int flags, char out[9])
+{
+  out[0] = (flags & CILK_FRAME_STOLEN) ? 'S' : '_';
+  out[1] = (flags & CILK_FRAME_UNSYNCHED) ? 'U' : '_';
+  out[2] = (flags & CILK_FRAME_DETACHED) ? 'D' : '_';
+  out[3] = (flags & CILK_FRAME_EXCEPTING) ? 'X' : '_';
+  out[4] = '\0';
+}
+#endif
+
+/* __cilkrts_save_except is called from the runtime epilogue
+   when a function is returning with an exception pending.
+
+   If the function has a parent to which it could return normally,
+   return and have the caller call _Unwind_Resume, the same as if
+   an exception filter had not matched.
+
+   Otherwise save the exception in the worker.
+
+   If this is a return from a ordinary call that must go through
+   the runtime, the assembly epilogue must have saved the call-saved
+   register state in the parent frame. */
+
+extern "C"
+CILK_ABI_THROWS_VOID
+__cilkrts_return_exception(__cilkrts_stack_frame *sf)
+{
+    __cilkrts_worker *w = sf->worker;
+    _Unwind_Exception *exc = (_Unwind_Exception *)sf->except_data;
+
+    CILK_ASSERT(sf->flags & CILK_FRAME_DETACHED);
+    sf->flags &= ~CILK_FRAME_DETACHED;
+
+   /*
+    * If we are in replay mode, and a steal occurred during the recording
+    * phase, stall till a steal actually occurs.
+    */
+    replay_wait_for_steal_if_parent_was_stolen(w);
+
+    /* If this is to be an abnormal return, save the active exception. */
+    if (!__cilkrts_pop_tail(w)) {
+        /* Write a record to the replay log for an attempt to return to a
+           stolen parent.  This must be done before the exception handler
+           invokes __cilkrts_leave_frame which will bump the pedigree so
+           the replay_wait_for_steal_if_parent_was_stolen() above will match on
+           replay */
+        replay_record_orphaned(w);
+
+        /* Now that the record/replay stuff is done, update the pedigree */
+        update_pedigree_on_leave_frame(w, sf);
+
+        /* Inline pop_frame; this may not be needed. */
+        w->current_stack_frame = sf->call_parent;
+        sf->call_parent = 0;
+        __cxa_eh_globals *state = __cxa_get_globals();
+
+#if DEBUG_EXCEPTIONS
+        fflush(stdout);
+        char decoded[9];
+        decode_flags(sf->flags, decoded);
+        fprintf(stderr, "__cilkrts_save_except W%u sf %p/%s exc %p [%u %p] suspend\n",
+                w->self, sf, decoded, exc,
+                state->uncaughtExceptions,
+                state->caughtExceptions);
+#endif
+
+        /* Like __cilkrts_save_exception_state except for setting the
+           rethrow flag. */
+        save_exception_info(w, state, exc, exc == NULL, "save_except");
+        {
+            full_frame *ff = w->l->frame_ff;
+            CILK_ASSERT(NULL == ff->pending_exception);
+            ff->pending_exception = w->l->pending_exception;
+            w->l->pending_exception = NULL;
+        }
+        __cilkrts_exception_from_spawn(w, sf); /* does not return */
+    }
+    /* This code path is taken when the parent is attached.  It is on
+       the same stack and part of the same full frame.  The caller is
+       cleaning up the Cilk frame during unwind and will reraise the
+       exception */
+
+    /* Now that the record/replay stuff is done, update the pedigree */
+    update_pedigree_on_leave_frame(w, sf);
+
+#if DEBUG_EXCEPTIONS /* DEBUG ONLY */
+    {
+        __cxa_eh_globals *state = __cxa_get_globals();
+
+        fflush(stdout);
+        char decoded[9];
+        decode_flags(sf->flags, decoded);
+        fprintf(stderr, "__cilkrts_save_except W%d %p/%s %p->%p [%u %p] escape\n",
+                w->self, sf, decoded, exc,
+                exc ? to_cxx(exc)->nextException : 0,
+                state->uncaughtExceptions,
+                state->caughtExceptions);
+
+        /* XXX This is triggering in the user thread which gets an exception
+           from somewhere but does not get the corresponding runtime exception
+           state.
+           XXX There might be two or more uncaught exceptions.  Test could be
+           (uncaught != 0) == (exc != 0).  First, design tests to see if that
+           case is otherwise handled correctly.  And what if there's an uncaught
+           exception that does not belong to this function?  I.e. this is a return
+           from spawn in a destructor. */
+        if (exc)
+            CILK_ASSERT((int)state->uncaughtExceptions > 0);
+        /*CILK_ASSERT(state->uncaughtExceptions == (exc != 0));*/
+    }
+#endif
+    
+    /* The parent is attached so this exception can be propagated normally. */
+    return;
+}
+
+/* Save the exception state into the full frame, which is exiting
+   or suspending. */
+extern "C"
+void __cilkrts_save_exception_state(__cilkrts_worker *w, full_frame *ff)
+{
+    save_exception_info(w, __cxa_get_globals(), 0, false, "undo-detach");
+    CILK_ASSERT(NULL == ff->pending_exception);
+    ff->pending_exception = w->l->pending_exception;
+    w->l->pending_exception = NULL;    
+}
+
+/* __cilkrts_c_sync_except is like __cilkrts_c_sync except that it
+   saves exception state.  __cilkrts_c_sync never returns here and
+   always reinstalls the saved exception state.
+
+   This function must be used because a parent of this function may
+   be propagating an uncaught exception.  The uncaught exception
+   count must be saved by the child and passed back to the parent. */
+
+extern "C"
+NORETURN __cilkrts_c_sync_except (__cilkrts_worker *w, __cilkrts_stack_frame *sf)
+{
+    __cxa_eh_globals *state = __cxa_get_globals();
+    _Unwind_Exception *exc = (_Unwind_Exception *)sf->except_data;
+
+    CILK_ASSERT((sf->flags & (CILK_FRAME_UNSYNCHED|CILK_FRAME_EXCEPTING)) ==
+                (CILK_FRAME_UNSYNCHED|CILK_FRAME_EXCEPTING));
+    sf->flags &= ~CILK_FRAME_EXCEPTING;
+
+#if DEBUG_EXCEPTIONS
+    fflush(stdout);
+    char decoded[9];
+    decode_flags(sf->flags, decoded);
+    if (exc)
+        fprintf(stderr, "__cilkrts_sync_except W%u %p/%s %p->%p [%u %p]\n",
+                w->self, sf, decoded, exc,
+                to_cxx(exc)->nextException,
+                state->uncaughtExceptions,
+                state->caughtExceptions);
+    else
+        fprintf(stderr, "__cilkrts_sync_except W%d %p/%s none [%u %p]\n",
+                w->self, sf, decoded,
+                state->uncaughtExceptions,
+                state->caughtExceptions);
+#endif
+
+    /* Here the identity of an rethrown exception is always known.
+       If exc is NULL this call is only to preserve parent state. */
+    save_exception_info(w, state, exc, false, "sync_except");
+#if 0
+    {
+        full_frame *ff = w->l->frame_ff;
+        CILK_ASSERT(NULL == ff->pending_exception);
+        ff->pending_exception = w->l->pending_exception;
+        w->l->pending_exception = NULL;    
+    }
+#endif
+    CILK_ASSERT(!std::uncaught_exception());
+    __cilkrts_c_sync(w, sf);
+}
+
+void
+pending_exception_info::destruct()
+{
+    if (active) {
+#if DEBUG_EXCEPTIONS
+        fprintf(stderr, "destroy exception info %p %p\n", this, active);
+#endif
+        _Unwind_DeleteException(active);
+        active = 0;
+    } else {
+#if DEBUG_EXCEPTIONS
+        fprintf(stderr, "destroy exception info %p\n", this);
+#endif
+    }
+    while (runtime_state.caughtExceptions) {
+        __cxa_exception *exc = runtime_state.caughtExceptions;
+        runtime_state.caughtExceptions = exc->nextException;
+#if DEBUG_EXCEPTIONS
+        fprintf(stderr, "destroy caught exception %p\n", this);
+#endif
+        _Unwind_DeleteException(&exc->unwindHeader);
+    }
+}
+
+/*
+ * __cilkrts_merge_pending_exceptions
+ *
+ * Merge the right exception record into the left.  The left is logically
+ * earlier.
+ *
+ * The active exception of E is
+ * E->active if it is non-NULL (in which case E->rethrow is false)
+ * unresolved if E->active is NULL and E->rethrow is true
+ * nil if E->active is NULL and E->rethrow is false
+ *
+ * The merged active exception is left active exception if it is not
+ * nil, otherwise the right.
+ *
+ * On entry the left state is synched and can not have an unresolved
+ * exception.  The merge may result in an unresolved exception.
+ *
+ * Due to scoping rules at most one of the caught exception lists is
+ * non-NULL.
+ */
+
+struct pending_exception_info *
+__cilkrts_merge_pending_exceptions (
+    __cilkrts_worker *w,
+    struct pending_exception_info *left,
+    struct pending_exception_info *right)
+{
+    /* If we've only got one exception, return it */
+
+    if (NULL == left) {
+#if DEBUG_EXCEPTIONS
+        if (right) {
+            char buf[40];
+            decode_exceptions(buf, sizeof buf, right);
+            fprintf(stderr, "__cilkrts merge W%u nil %p -> %p %s\n",
+                    w->self, right, right, buf);
+        }
+#endif
+        return right;
+    }
+
+    if (NULL == right) {
+#if DEBUG_EXCEPTIONS
+        if (left) {
+            char buf[40];
+            decode_exceptions(buf, sizeof buf, left);
+            fprintf(stderr, "__cilkrts merge W%u %p nil -> %p %s\n",
+                    w->self, left, left, buf);
+        }
+#endif
+        return left;
+    }
+
+#if CILK_LIB_DEBUG
+    /*volatile struct pending_exception_info left_in = *left, right_in = *right;*/
+    left->check();
+    right->check();
+#endif
+
+#if DEBUG_EXCEPTIONS
+    {
+        char buf1[40], buf2[40];
+        decode_exceptions(buf1, sizeof buf1, left);
+        decode_exceptions(buf2, sizeof buf2, right);
+        fprintf(stderr, "__cilkrts merge W%u %p %s %p %s\n",
+                w->self, left, buf1, right, buf2);
+    }
+#endif
+
+    /* It should not be possible for both left and right to
+       have accumulated catch blocks.
+
+       The left exception record may always have a catch
+       chain it kept when its parent was stolen.
+
+       If they are siblings, the right sibling should not
+       have accumulated any net catches.  (Catch is lexically
+       scoped.)
+
+       If the right frame is a parent, it should not have entered
+       a catch block without syncing first.  If it spawned in a
+       catch block, the child got its catch. */
+    __cxa_exception *caught = left->runtime_state.caughtExceptions;
+    if (caught)
+        CILK_ASSERT(!right->runtime_state.caughtExceptions);
+    else {
+        CILK_ASSERT(!left->rethrow);
+        left->rethrow = right->rethrow;
+        left->runtime_state.caughtExceptions = caught = right->runtime_state.caughtExceptions;
+        right->runtime_state.caughtExceptions = NULL;
+    }
+
+    /* Merge the uncaught exception and count of uncaught exceptions. */
+    const unsigned int right_uncaught = right->runtime_state.uncaughtExceptions;
+    if (!left->active){
+        left->active = right->active; /* could be NULL */
+        right->active = 0;
+        left->runtime_state.uncaughtExceptions += right_uncaught;
+        if (left->active)
+            /* assert is C++ exception */
+            /*CILK_ASSERT(__cxxabiv1::__is_gxx_exception_class(left->active->exception_class))*/;
+    } else {
+        /* Subtract 1 if the right exception is being destructed. */
+        left->runtime_state.uncaughtExceptions += right_uncaught - (right->active != 0);
+    }
+
+    right->destruct();
+    __cilkrts_frame_free(w, right, sizeof *right);
+
+    /* If there is no state left, return NULL. */
+    if (left->empty()) {
+        left->destruct();
+        __cilkrts_frame_free(w, left, sizeof *left);
+        left = NULL;
+    }
+
+#if CILK_LIB_DEBUG
+    if (left)
+        left->check();
+#endif
+
+    return left;
+}
+
+#if 0
+/* __cilkrts_c_resume_except is called from the assembly language
+   restart code when a resumed frame has a pending exception.
+
+   The handler count negation on rethrow was done when the throw was
+   resolved.
+
+   The assembly language runtime must make the throw unwind to
+   the sync, spawn, or other location where the exception should
+   be injected.  (This should not happen after a spawn but nothing
+   here depends on there being no exception on steal.)
+
+   This function is unused in the Intel stack based system. */
+extern "C"
+void __cilkrts_c_resume_except (_Unwind_Exception *exc)
+{
+#if DEBUG_EXCEPTIONS
+    fprintf(stderr, "resume exception %p\n", exc);
+#endif
+    _Unwind_Reason_Code why = _Unwind_RaiseException(exc);
+    __cilkrts_bug ("Cilk runtime error: failed to reinstate suspended exception %p (%d)\n", exc, why);
+}
+#endif
+
+/* Restore the caught exception chain.  This assumes no C++ exception
+   code will run before the frame is resumed.  If there is no exception
+   to be resumed free the object. */
+
+extern "C"
+void __cilkrts_setup_for_execution_sysdep(__cilkrts_worker *w, full_frame *ff)
+{
+    // ASSERT: We own w->lock and ff->lock || P == 1
+
+    __cxa_eh_globals *state = __cxa_get_globals ();
+    struct pending_exception_info *info = w->l->pending_exception;
+
+    if (info == NULL)
+        return;
+
+    w->l->pending_exception = 0;
+
+#if DEBUG_EXCEPTIONS
+    _Unwind_Exception *exc = info->active;
+    if (exc) {
+        fflush(stdout);
+        fprintf(stderr, "__cilkrts_resume_except W%u %p->%p [%u %p]\n",
+                w->self, exc,
+                to_cxx(exc)->nextException,
+                info->runtime_state.uncaughtExceptions,
+                info->runtime_state.caughtExceptions);
+        /*CILK_ASSERT(info->runtime_state.uncaughtExceptions > 0);*/
+    }
+#endif
+
+    if (state->uncaughtExceptions || state->caughtExceptions)
+        __cilkrts_bug("W%u: resuming with non-empty prior exception state %u %p\n", state->uncaughtExceptions, state->caughtExceptions);
+
+    *state = info->runtime_state;
+    info->runtime_state.caughtExceptions = 0;
+    info->runtime_state.uncaughtExceptions = 0;
+
+    if (info->rethrow) {
+        info->rethrow = false;
+        /* Resuming function will rethrow.  Runtime calls
+           std::terminate if there is no caught exception. */
+        ff->call_stack->flags |= CILK_FRAME_EXCEPTING;
+    }
+    if (info->active) {
+        ff->call_stack->flags |= CILK_FRAME_EXCEPTING;
+        ff->call_stack->except_data = info->active;
+        info->active = 0;
+    }
+
+    if (info->empty()) {
+        info->destruct();
+        __cilkrts_frame_free(w, info, sizeof *info);
+        w->l->pending_exception = NULL;
+    }
+
+#if CILK_LIB_DEBUG
+    if (ff->call_stack->except_data)
+        CILK_ASSERT(std::uncaught_exception());
+#endif
+}
+
+#if 0
+extern "C"
+struct pending_exception_info *__cilkrts_get_exception(__cilkrts_worker *w,
+                                                       __cilkrts_stack_frame *sf)
+{
+    struct pending_exception_info *info = w->l->pending_exception;
+
+    if (info == NULL) {
+        sf->flags &= ~CILK_FRAME_EXCEPTING;
+        return 0;
+    }
+
+    w->l->pending_exception = NULL;
+
+    /* This exception goes into the frame. */
+
+    _Unwind_Exception *exc = info->active;
+    info->active = NULL;
+    info->destruct();
+    __cilkrts_frame_free(w, info, sizeof *info);
+    info = 0;
+    sf->flags |= CILK_FRAME_EXCEPTING;
+    sf->exception = exc;
+    return 0;
+}
+#endif
+
+extern "C"
+void __attribute__((nonnull)) __cilkrts_gcc_rethrow(__cilkrts_stack_frame *sf)
+{
+#ifdef __CYGWIN__
+    // Cygwin doesn't support exceptions, so _Unwind_Resume isn't available
+    // Which means we can't support exceptions either
+    __cilkrts_bug("The Cygwin implementation of the Intel Cilk Plus runtime doesn't support exceptions\n");
+#else
+    if (sf->except_data) {
+#if CILK_LIB_DEBUG
+        CILK_ASSERT(std::uncaught_exception());
+#endif        
+        _Unwind_Resume ((_Unwind_Exception *)sf->except_data);
+    } else {
+        throw;
+    }
+#endif  // __CYGWIN__
+}
+
+/* End except-gcc.cpp */
+
diff --git a/libcilkrts/runtime/except-gcc.h b/libcilkrts/runtime/except-gcc.h
new file mode 100644 (file)
index 0000000..aa76adb
--- /dev/null
@@ -0,0 +1,146 @@
+/* except-gcc.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file except-gcc.h
+ *
+ * @brief ABI for gcc exception handling.
+ *
+ * @par Origin
+ * The code below is generally copied from the Intel Itanium ABI (Intel
+ * download 245370).
+ */
+
+#ifndef INCLUDED_EXCEPT_GCC_DOT_H
+#define INCLUDED_EXCEPT_GCC_DOT_H
+
+#ifndef __cplusplus
+#   error except-gcc.h should be used in C++ code only.
+#endif
+
+#include <cilk/common.h>
+#include <exception>
+#include <typeinfo>
+
+struct __cxa_exception;
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/** Unwind reason code (Itanium ABI 6.1.2.1) */
+typedef enum _Unwind_Reason_Code {
+    _URC_NO_REASON = 0,
+    _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+    _URC_FATAL_PHASE2_ERROR = 2,
+    _URC_FATAL_PHASE1_ERROR = 3,
+    _URC_NORMAL_STOP = 4,
+    _URC_END_OF_STACK = 5,
+    _URC_HANDLER_FOUND = 6,
+    _URC_INSTALL_CONTEXT = 7,
+    _URC_CONTINUE_UNWIND = 8
+} _Unwind_Reason_Code;
+
+typedef struct _Unwind_Exception _Unwind_Exception;
+
+/** Exception cleanup function pointer (Itanium ABI 6.1.2.2) */
+typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code reason,
+                                             _Unwind_Exception *exc);
+
+/**
+ * @brief Exception undwinding information
+ *
+ * This is copied from the Intel Itanium ABI except that the
+ * private fields are declared unsigned long for binary
+ * compatibility with gcc/g++ on 32 bit machines.
+ */
+struct _Unwind_Exception
+{
+    uint64_t                     exception_class;
+    _Unwind_Exception_Cleanup_Fn exception_cleanup;
+    unsigned long                private_1;
+    unsigned long                private_2;
+};
+
+/** Throw or rethrow an exception */
+_Unwind_Reason_Code
+_Unwind_RaiseException(_Unwind_Exception *exception_object);
+
+/** Resume an exception other than by rethrowing it. */
+void _Unwind_Resume(_Unwind_Exception *exception_object);
+
+/** Delete an exception object */
+void _Unwind_DeleteException(_Unwind_Exception *exception_object);
+
+/**
+ * C++ exception ABI.
+ *  The following declarations are from
+ *
+ * http://www.codesourcery.com/public/cxx-abi/abi-eh.html#cxx-abi
+ */
+
+struct __cxa_exception {
+    std::type_info *        exceptionType;
+    void (*exceptionDestructor)(void *); 
+    std::unexpected_handler unexpectedHandler;
+    std::terminate_handler  terminateHandler;
+    __cxa_exception *       nextException;
+
+    int                     handlerCount;
+    int                     handlerSwitchValue;
+    const char *            actionRecord;
+    const char *            languageSpecificData;
+    void *                  catchTemp;
+    void *                  adjustedPtr;
+
+    _Unwind_Exception       unwindHeader;
+};
+
+static inline __cxa_exception *to_cxx(_Unwind_Exception *e)
+{
+    return ((__cxa_exception *)(e+1)) - 1;
+}
+
+typedef struct __cxa_eh_globals {
+    __cxa_exception *caughtExceptions;
+    unsigned int     uncaughtExceptions;
+} __cxa_eh_globals;
+
+__cxa_eh_globals*__cxa_get_globals(void) throw();
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_EXCEPT_GCC_DOT_H)
diff --git a/libcilkrts/runtime/except.h b/libcilkrts/runtime/except.h
new file mode 100644 (file)
index 0000000..58e2238
--- /dev/null
@@ -0,0 +1,123 @@
+/* except.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file except.h
+ *
+ * @brief Common definitions for the various implementations of exception
+ * handling.
+ */
+
+#ifndef INCLUDED_EXCEPT_DOT_H
+#define INCLUDED_EXCEPT_DOT_H
+
+#include <cilk/common.h>
+#include <internal/abi.h>
+#include "full_frame.h"
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * OS-dependent information about an exception that's being moved between
+ * strands.
+ */
+typedef struct pending_exception_info pending_exception_info;
+
+/**
+ * Merge the right exception record into the left.  The left is logically
+ * earlier.
+ *
+ * On entry the left state is synched and can not have an unresolved
+ * exception.  The merge may result in an unresolved exception.
+ *
+ * If there is both a right and left exception, the right exception will
+ * be disposed of in preference to the left exception, destructing the
+ * exception object.
+ *
+ * @param w The worker that is preparing to resume execution.
+ * @param left_exception The exception that would have happened earlier
+ * if the code executed serially.  Can be NULL if the left strand has not
+ * raised an exception.
+ * @param right_exception The exception that would have happened later
+ * if the code executed serially.  Can be NULL if the right strand has not
+ * raised an exception.
+ *
+ * @return NULL if there both the right and left exception are NULL. This
+ * indicates that there are no pending exceptions.
+ * @return The pending exception that is to be raised to continue searching
+ * for a catch block to handle the exception.
+ */
+COMMON_SYSDEP
+struct pending_exception_info *__cilkrts_merge_pending_exceptions(
+    __cilkrts_worker *w,
+    pending_exception_info *left_exception,
+    pending_exception_info *right_exception);
+
+/**
+ * Move the exception information from the worker to the full_frame.
+ *
+ * @param w The worker which is suspending work on a full_frame.
+ * @param ff The full_frame which is being suspended.
+ */
+COMMON_SYSDEP
+void __cilkrts_save_exception_state(__cilkrts_worker *w,
+                                    full_frame *ff);
+
+/**
+ * Function to delete pending exception.  This will delete the
+ * exception object and then free the stack/fiber.
+ *
+ * @param w The worker we're running on.
+ * @param pei The pending exception to be delete
+ * @param delete_object Unused.  Should always be 1.
+ */
+void delete_exception_obj (__cilkrts_worker *w,
+                           struct pending_exception_info *pei,
+                           int delete_object);
+
+#ifndef _WIN32
+/* gcc-style exception handling */
+NON_COMMON NORETURN __cilkrts_c_sync_except(__cilkrts_worker *w,
+                                            __cilkrts_stack_frame *sf);
+NON_COMMON void __attribute__((nonnull))
+__cilkrts_gcc_rethrow(__cilkrts_stack_frame *sf);
+#endif
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_EXCEPT_DOT_H)
diff --git a/libcilkrts/runtime/frame_malloc.c b/libcilkrts/runtime/frame_malloc.c
new file mode 100644 (file)
index 0000000..0b38bd2
--- /dev/null
@@ -0,0 +1,462 @@
+/* frame_malloc.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#include "frame_malloc.h"
+#include "bug.h"
+#include "local_state.h"
+#include "cilk_malloc.h"
+
+#ifndef __VXWORKS__
+#include <memory.h>
+#endif
+
+/* #define USE_MMAP 1 */ 
+#if USE_MMAP
+#define __USE_MISC 1
+#include <sys/mman.h>
+#include <errno.h>
+#endif
+
+// Define to fill the stack frame header with the fill character when pushing
+// it on a free list.  Note that this should be #ifdef'd out when checked in!
+
+#ifdef _DEBUG
+#define HEADER_FILL_CHAR 0xbf
+#endif
+
+// HEADER_FILL_CHAR should not be defined when checked in, so put out a warning
+// message if this is a release build
+
+#if defined(NDEBUG) && defined (HEADER_FILL_CHAR)
+#pragma message ("Warning: HEADER_FILL_CHAR defined for a release build")
+#endif
+
+static void allocate_batch(__cilkrts_worker *w, int bucket, size_t size);
+
+#ifndef _WIN32
+
+const unsigned short __cilkrts_bucket_sizes[FRAME_MALLOC_NBUCKETS] =
+{
+    64, 128, 256, 512, 1024, 2048
+};
+
+#define FRAME_MALLOC_BUCKET_TO_SIZE(bucket) __cilkrts_bucket_sizes[bucket]
+
+/* threshold above which we use slow malloc */
+#define FRAME_MALLOC_MAX_SIZE 2048
+
+#else // _WIN32
+
+/* Note that this must match the implementation of framesz_to_bucket in
+ * asmilator/layout.ml! */
+#define FRAME_MALLOC_BUCKET_TO_SIZE(bucket) ((size_t)(64 << (bucket)))
+
+/* threshold above which we use slow malloc */
+#define FRAME_MALLOC_MAX_SIZE                                   \
+    FRAME_MALLOC_BUCKET_TO_SIZE(FRAME_MALLOC_NBUCKETS - 1)
+
+#endif // _WIN32
+
+/* utility procedures */
+static void push(struct free_list **b, struct free_list *p)
+{
+#ifdef HEADER_FILL_CHAR
+    memset (p, HEADER_FILL_CHAR, FRAME_MALLOC_BUCKET_TO_SIZE(0));
+#endif
+    /* cons! onto free list */
+    p->cdr = *b;
+    *b = p;
+}
+
+static struct free_list *pop(struct free_list **b)
+{
+    struct free_list *p = *b;
+    if (p) 
+        *b = p->cdr;
+    return p;
+}
+
+/*************************************************************
+  global allocator:
+*************************************************************/
+/* request slightly less than 2^K from the OS, which after malloc
+   overhead and alignment should end up filling each VM page almost
+   completely.  128 is a guess of the total malloc overhead and cache
+   line alignment */
+#define FRAME_MALLOC_CHUNK (32 * 1024 - 128)
+
+/** Implements linked list of frames */
+struct pool_cons {
+    char *p;                /**< This element of the list */
+    struct pool_cons *cdr;  /**< Remainder of the list */
+};
+
+static void extend_global_pool(global_state_t *g)
+{
+    /* FIXME: memalign to a cache line? */
+    struct pool_cons *c = (struct pool_cons *)__cilkrts_malloc(sizeof(*c));
+    g->frame_malloc.pool_begin = 
+        (char *)__cilkrts_malloc((size_t)FRAME_MALLOC_CHUNK);
+    g->frame_malloc.pool_end = 
+        g->frame_malloc.pool_begin + FRAME_MALLOC_CHUNK;
+    g->frame_malloc.allocated_from_os += FRAME_MALLOC_CHUNK;
+    c->p = g->frame_malloc.pool_begin;
+    c->cdr = g->frame_malloc.pool_list;
+    g->frame_malloc.pool_list = c;
+}
+
+/* the size is already canonicalized at this point */
+static struct free_list *global_alloc(global_state_t *g, int bucket)
+{
+    struct free_list *mem;
+    size_t size;
+
+    CILK_ASSERT(bucket < FRAME_MALLOC_NBUCKETS);
+    size = FRAME_MALLOC_BUCKET_TO_SIZE(bucket);
+    g->frame_malloc.allocated_from_global_pool += size;
+
+    if (!(mem = pop(&g->frame_malloc.global_free_list[bucket]))) {
+
+        CILK_ASSERT(g->frame_malloc.pool_begin <= g->frame_malloc.pool_end);
+        if (g->frame_malloc.pool_begin + size > g->frame_malloc.pool_end) {
+            /* We waste the fragment of pool. */
+            g->frame_malloc.wasted +=
+                g->frame_malloc.pool_end - g->frame_malloc.pool_begin;
+            extend_global_pool(g);
+        }
+        mem = (struct free_list *)g->frame_malloc.pool_begin;
+        g->frame_malloc.pool_begin += size;
+    }
+
+    return mem;
+}
+
+static void global_free(global_state_t *g, void *mem, int bucket)
+{
+    size_t size;
+
+    CILK_ASSERT(bucket < FRAME_MALLOC_NBUCKETS);
+    size = FRAME_MALLOC_BUCKET_TO_SIZE(bucket);
+    g->frame_malloc.allocated_from_global_pool -= size;
+
+    push(&g->frame_malloc.global_free_list[bucket], mem);
+}
+
+void __cilkrts_frame_malloc_global_init(global_state_t *g)
+{
+    int i;
+
+    __cilkrts_mutex_init(&g->frame_malloc.lock); 
+    g->frame_malloc.check_for_leaks = 1;
+    g->frame_malloc.pool_list = 0;
+    g->frame_malloc.pool_begin = 0;
+    g->frame_malloc.pool_end = 0;
+    g->frame_malloc.batch_size = 8000;
+    g->frame_malloc.potential_limit = 4 * g->frame_malloc.batch_size;
+    g->frame_malloc.allocated_from_os = 0;
+    g->frame_malloc.allocated_from_global_pool = 0;
+    g->frame_malloc.wasted = 0;
+    for (i = 0; i < FRAME_MALLOC_NBUCKETS; ++i) 
+        g->frame_malloc.global_free_list[i] = 0;
+}
+
+// Counts how many bytes are in the global free list.
+static size_t count_memory_in_global_list(global_state_t *g)
+{
+
+    // Count the memory remaining in the global free list.
+    size_t size_remaining_in_global_list = 0;
+    int i;
+    for (i = 0; i < FRAME_MALLOC_NBUCKETS; ++i) {
+        struct free_list *p;
+        size_t size_in_bucket = 0;
+        p = g->frame_malloc.global_free_list[i];
+
+        while (p) {
+            size_in_bucket += FRAME_MALLOC_BUCKET_TO_SIZE(i);
+            p = p->cdr;
+        }
+        size_remaining_in_global_list += size_in_bucket;
+    }
+    return size_remaining_in_global_list;
+}
+
+
+void __cilkrts_frame_malloc_global_cleanup(global_state_t *g)
+{
+    struct pool_cons *c;
+
+    if (g->frame_malloc.check_for_leaks) {
+        size_t memory_in_global_list = count_memory_in_global_list(g);
+        // TBD: This check is weak.  Short of memory corruption,
+        // I don't see how we have more memory in the free list
+        // than allocated from the os.
+        // Ideally, we should count the memory in the global free list
+        // and check that we have it all.  But I believe the runtime
+        // itself also uses some memory, which is not being tracked.
+        if (memory_in_global_list > g->frame_malloc.allocated_from_os) {
+            __cilkrts_bug("\nError. The Cilk runtime data structures may have been corrupted.\n");
+        }
+    }
+    
+    while ((c = g->frame_malloc.pool_list)) {
+        g->frame_malloc.pool_list = c->cdr;
+        __cilkrts_free(c->p);
+        __cilkrts_free(c);
+    }
+
+    __cilkrts_mutex_destroy(0, &g->frame_malloc.lock);
+
+    // Check that all the memory moved from the global pool into
+    // workers has been returned to the global pool.
+    if (g->frame_malloc.check_for_leaks
+        && (g->frame_malloc.allocated_from_global_pool != 0))
+    {
+        __cilkrts_bug("\n"
+                      "---------------------------" "\n"
+                      "  MEMORY LEAK DETECTED!!!  " "\n"
+                      "---------------------------" "\n"
+                      "\n"
+            );
+    }
+}
+
+/*************************************************************
+  per-worker allocator
+*************************************************************/
+/* allocate a batch of frames of size SIZE from the global pool and
+   store them in the worker's free list */
+static void allocate_batch(__cilkrts_worker *w, int bucket, size_t size)
+{
+    global_state_t *g = w->g;
+
+    __cilkrts_mutex_lock(w, &g->frame_malloc.lock); {
+#if USE_MMAP
+        char *p = mmap(0, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+        if (p == MAP_FAILED)
+            __cilkrts_bug("mmap failed %d", errno);
+        assert(size < 4096);
+        assert(p != MAP_FAILED);
+        mprotect(p, 4096, PROT_NONE);
+        mprotect(p + 8192, 4096, PROT_NONE);
+        w->l->bucket_potential[bucket] += size;
+        push(&w->l->free_list[bucket], (struct free_list *)(p + 8192 - size));
+#else
+        size_t bytes_allocated = 0;
+        do {
+            w->l->bucket_potential[bucket] += size;
+            bytes_allocated += size;
+            push(&w->l->free_list[bucket], global_alloc(g, bucket));
+        } while (bytes_allocated < g->frame_malloc.batch_size);
+#endif
+    } __cilkrts_mutex_unlock(w, &g->frame_malloc.lock);
+
+}
+
+static void gc_bucket(__cilkrts_worker *w, int bucket, size_t size)
+{
+    struct free_list *p, *q;
+    global_state_t *g = w->g;
+    size_t pot = w->l->bucket_potential[bucket];
+    size_t newpot;
+
+    /* Keep up to POT/2 elements in the free list.  The cost of
+       counting up to POT/2 is amortized against POT. */
+    newpot = 0;
+    for (newpot = 0, p = w->l->free_list[bucket]; p && 2 * newpot < pot; 
+         p = p->cdr, newpot += size)
+        ;
+    w->l->bucket_potential[bucket] = newpot;
+
+    if (p) {
+        /* free the rest of the list.  The cost of grabbing the lock
+           is amortized against POT/2; the cost of traversing the rest
+           of the list is amortized against the free operation that
+           puts the element on the list. */
+        __cilkrts_mutex_lock(w, &g->frame_malloc.lock); {
+            while ((q = pop(&p->cdr)))
+#if USE_MMAP
+                munmap((char *)q + size - 8192, 12288);
+#else
+                global_free(g, q, bucket);
+#endif
+        } __cilkrts_mutex_unlock(w, &g->frame_malloc.lock);
+    }
+}
+
+// Free all the memory in this bucket for the specified worker,
+// returning it to the global pool's free list.
+static void move_bucket_to_global_free_list(__cilkrts_worker *w,
+                                            int bucket)
+{
+    struct free_list *p, *q;
+    global_state_t *g = w->g;
+    p = w->l->free_list[bucket];
+    
+    if (p) {
+        __cilkrts_mutex_lock(w, &g->frame_malloc.lock); {
+            while ((q = pop(&p))) {
+#if USE_MMAP
+                size_t size = FRAME_MALLOC_BUCKET_TO_SIZE(bucket);
+                munmap((char *)q + size - 8192, 12288);
+#else
+                global_free(g, q, bucket);
+#endif
+            }
+        } __cilkrts_mutex_unlock(w, &g->frame_malloc.lock);
+    }
+
+    // I'm not sure this does anything useful now, since
+    // the worker is about to be destroyed. But why not?
+    w->l->bucket_potential[bucket] = 0;
+}
+
+static int bucket_of_size(size_t size)
+{
+    int i;
+
+    for (i = 0; i < FRAME_MALLOC_NBUCKETS; ++i)
+        if (size <= FRAME_MALLOC_BUCKET_TO_SIZE(i))
+            return i;
+
+    CILK_ASSERT(0 /* can't happen */);
+    return -1;
+}
+
+size_t __cilkrts_frame_malloc_roundup(size_t size)
+{
+    if (size > FRAME_MALLOC_MAX_SIZE) {
+        /* nothing, leave it alone */
+    } else {
+        int bucket = bucket_of_size(size);
+        size = FRAME_MALLOC_BUCKET_TO_SIZE(bucket);
+    }
+    return size;
+}
+
+size_t __cilkrts_size_of_bucket(int bucket)
+{
+    CILK_ASSERT(bucket >= 0 && bucket < FRAME_MALLOC_NBUCKETS);
+    return FRAME_MALLOC_BUCKET_TO_SIZE(bucket);
+}
+
+void *__cilkrts_frame_malloc(__cilkrts_worker *w, size_t size)
+{
+    int bucket;
+    void *mem;
+
+    /* if too large, or if no worker, fall back to __cilkrts_malloc()  */
+    if (!w || size > FRAME_MALLOC_MAX_SIZE) {
+        NOTE_INTERVAL(w, INTERVAL_FRAME_ALLOC_LARGE);
+        return __cilkrts_malloc(size);
+    }
+
+    START_INTERVAL(w, INTERVAL_FRAME_ALLOC); {
+        bucket = bucket_of_size(size);
+        size = FRAME_MALLOC_BUCKET_TO_SIZE(bucket);
+
+        while (!(mem = pop(&w->l->free_list[bucket]))) {
+            /* get a batch of frames from the global pool */
+            START_INTERVAL(w, INTERVAL_FRAME_ALLOC_GLOBAL) {
+                allocate_batch(w, bucket, size);
+            } STOP_INTERVAL(w, INTERVAL_FRAME_ALLOC_GLOBAL);
+        }
+    } STOP_INTERVAL(w, INTERVAL_FRAME_ALLOC);
+
+    return mem;
+}
+
+void __cilkrts_frame_free(__cilkrts_worker *w, void *p0, size_t size)
+{
+    int bucket;
+    struct free_list *p = (struct free_list *)p0;
+
+    /* if too large, or if no worker, fall back to __cilkrts_free()  */
+    if (!w || size > FRAME_MALLOC_MAX_SIZE) {
+        NOTE_INTERVAL(w, INTERVAL_FRAME_FREE_LARGE);
+        __cilkrts_free(p);
+        return;
+    }
+
+#if CILK_LIB_DEBUG
+    *(volatile long *)w;
+#endif
+
+    START_INTERVAL(w, INTERVAL_FRAME_FREE); {
+        bucket = bucket_of_size(size);
+        size = FRAME_MALLOC_BUCKET_TO_SIZE(bucket);
+        w->l->bucket_potential[bucket] += size;
+        push(&w->l->free_list[bucket], p);
+        if (w->l->bucket_potential[bucket] >
+            w->g->frame_malloc.potential_limit) {
+            START_INTERVAL(w, INTERVAL_FRAME_FREE_GLOBAL) {
+                gc_bucket(w, bucket, size);
+            } STOP_INTERVAL(w, INTERVAL_FRAME_FREE_GLOBAL);
+        }
+    } STOP_INTERVAL(w, INTERVAL_FRAME_FREE);
+}
+
+void __cilkrts_frame_malloc_per_worker_init(__cilkrts_worker *w)
+{
+    int i;
+    local_state *l = w->l;
+
+    for (i = 0; i < FRAME_MALLOC_NBUCKETS; ++i) {
+        l->free_list[i] = 0;
+        l->bucket_potential[i] = 0;
+    }
+}
+
+void __cilkrts_frame_malloc_per_worker_cleanup(__cilkrts_worker *w)
+{
+    int i;
+    // Move memory to the global pool.  This operation
+    // ensures the memory does not become unreachable / leak
+    // when the worker is destroyed.
+    for (i = 0; i < FRAME_MALLOC_NBUCKETS; ++i) {
+        move_bucket_to_global_free_list(w, i);
+    }
+}
+
+/*
+  Local Variables: **
+  c-file-style:"bsd" **
+  c-basic-offset:4 **
+  indent-tabs-mode:nil **
+  End: **
+*/
diff --git a/libcilkrts/runtime/frame_malloc.h b/libcilkrts/runtime/frame_malloc.h
new file mode 100644 (file)
index 0000000..d412fb6
--- /dev/null
@@ -0,0 +1,205 @@
+/* frame_malloc.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file frame_malloc.h
+ *
+ * @brief The frame allocation routines manage memory in a per-worker pool.
+ *
+ * The name "frame malloc" refers to an earlier implementation of Cilk which
+ * allocated frames from the heap using this allocator.
+ */
+
+#ifndef INCLUDED_FRAME_MALLOC_DOT_H
+#define INCLUDED_FRAME_MALLOC_DOT_H
+
+#include "worker_mutex.h"
+#include "rts-common.h"
+#include <internal/abi.h>  // __cilkrts_worker
+
+#ifdef __cplusplus
+#   include <cstddef>
+#else
+#   include <stddef.h>
+#endif
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * Number of buckets.  Gives us buckets to hold  64, 128, 256, 512, 1024
+ * and 2048 bytes
+ */
+#define FRAME_MALLOC_NBUCKETS 6
+
+/** Layout of frames when unallocated */
+struct free_list {
+     /** Pointer to next free frame */
+     struct free_list *cdr;
+};
+
+/** per-worker memory cache */
+struct __cilkrts_frame_cache
+{
+    /** Mutex to serialize access */
+    struct mutex lock;
+
+    /** Linked list of frames */
+    struct pool_cons *pool_list;
+
+    /** Low bound of memory in pool */
+    char *pool_begin;
+
+    /** High bound of memory in pool */
+    char *pool_end;
+
+    /** Global free-list buckets */
+    struct free_list *global_free_list[FRAME_MALLOC_NBUCKETS];
+
+    /**
+     * How many bytes to obtain at once from the global pool
+     * (approximately)
+     */
+    size_t batch_size;
+
+    /** Garbage-collect a bucket when its potential exceeds the limit */
+    size_t potential_limit;
+
+    /** If TRUE, check for memory leaks at the end of execution */
+    int check_for_leaks;
+
+    /** Bytes of memory allocated from the OS by the global cache */
+    size_t allocated_from_os;
+
+    /** Tracks memory allocated by a chunk that isn't a full bucket size */
+    size_t wasted;
+
+    /** Bytes of memory allocated from the global cache */
+    size_t allocated_from_global_pool;
+};
+
+/**
+ * Allocate memory from the per-worker pool. If the size is too large, or
+ * if we're given a NULL worker, the memory is allocated using
+ * __cilkrts_malloc().
+ *
+ * @param w The worker to allocate the memory from.
+ * @param size The number of bytes to allocate.
+ *
+ * @return pointer to allocated memory block.
+ */
+COMMON_PORTABLE
+void *__cilkrts_frame_malloc(__cilkrts_worker *w,
+                             size_t size) cilk_nothrow;
+
+/**
+ * Return memory to the per-worker pool. If the size is too large, or
+ * if we're given a NULL worker, the memory is freed using
+ * __cilkrts_free().
+ *
+ * @param w The worker to allocate the memory from.
+ * @param p The memory block to be released.
+ * @param size The size of the block, in bytes.
+ */
+COMMON_PORTABLE
+void __cilkrts_frame_free(__cilkrts_worker *w,
+                          void*  p,
+                          size_t size) cilk_nothrow;
+
+/**
+ * Destroy the global cache stored in the global state, freeing all memory
+ * to the global heap.  Checks whether any memory has been allocated but
+ * not freed.
+ *
+ * @param g The global state.
+ */
+COMMON_PORTABLE
+void __cilkrts_frame_malloc_global_cleanup(global_state_t *g);
+
+/**
+ * Initialize a worker's memory cache.  Initially it is empty.
+ *
+ * @param w The worker who's memory cache is to be initialized.
+ */
+COMMON_PORTABLE
+void __cilkrts_frame_malloc_per_worker_init(__cilkrts_worker *w);
+
+/**
+ * If check_for_leaks is set in the global state's memory cache, free any
+ * memory in the worker's memory cache.
+ *
+ * If check_for_leask is not set, nothing happens.
+ *
+ * @param w The worker who's memory cache is to be cleaned up.
+ */
+COMMON_PORTABLE
+void __cilkrts_frame_malloc_per_worker_cleanup(__cilkrts_worker *w);
+
+/**
+ * Round a number of bytes to the size of the smallest bucket that will
+ * hold it.  If the size is bigger than the largest bucket, the value is
+ * unchanged.
+ *
+ * @param size Number of bytes to be rounded up to the nearest bucket size.
+ *
+ * @return The size of the smallest bucket that will hold the specified bytes.
+ */
+COMMON_PORTABLE
+size_t __cilkrts_frame_malloc_roundup(size_t size) cilk_nothrow;
+
+/**
+ * Return the number of bytes that can fit into a bucket.
+ *
+ * Preconditions:
+ *  - The index must be in the range 0 - FRAME_MALLOC_NBUCKETS
+ *
+ * @param bucket Index of the bucket to be sized.
+ */
+COMMON_PORTABLE
+size_t __cilkrts_size_of_bucket(int bucket) cilk_nothrow;
+
+/**
+ * Initialize the global memory cache.
+ *
+ * @param g The global state.
+ */
+COMMON_PORTABLE
+void __cilkrts_frame_malloc_global_init(global_state_t *g);
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_FRAME_MALLOC_DOT_H)
diff --git a/libcilkrts/runtime/full_frame.c b/libcilkrts/runtime/full_frame.c
new file mode 100644 (file)
index 0000000..9ccfd11
--- /dev/null
@@ -0,0 +1,181 @@
+/* full_frame.c                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2010-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+#include "full_frame.h"
+#include "stats.h"
+#include "os.h"
+#include "bug.h"
+#include "jmpbuf.h"
+#include "frame_malloc.h"
+
+COMMON_PORTABLE
+full_frame *__cilkrts_make_full_frame(__cilkrts_worker *w,
+                                      __cilkrts_stack_frame *sf)
+{
+    full_frame *ff;
+
+    START_INTERVAL(w, INTERVAL_ALLOC_FULL_FRAME) {
+        ff = (full_frame *)__cilkrts_frame_malloc(w, sizeof(*ff));
+        __cilkrts_mutex_init(&ff->lock);
+
+        ff->full_frame_magic_0 = FULL_FRAME_MAGIC_0;
+        ff->join_counter = 0;
+        ff->parent = 0;
+        ff->rightmost_child = 0;
+        ff->left_sibling = ff->right_sibling = 0;
+        ff->call_stack = sf;
+        ff->is_call_child = 0;
+        ff->simulated_stolen = 0;
+       ff->children_reducer_map = ff->right_reducer_map = 0;
+        ff->pending_exception = 
+            ff->child_pending_exception = 
+            ff->right_pending_exception = NULL;
+
+        ff->sync_sp = 0;
+#ifdef _WIN32
+        ff->exception_sp = 0;
+        ff->trylevel = (unsigned long)-1;
+        ff->registration = 0;
+#endif
+       ff->frame_size = 0;
+        ff->fiber_self = 0;
+        ff->fiber_child = 0;
+
+        ff->sync_master = 0;
+
+        /*__cilkrts_init_full_frame_sysdep(w, ff);*/
+        ff->full_frame_magic_1 = FULL_FRAME_MAGIC_1;
+    } STOP_INTERVAL(w, INTERVAL_ALLOC_FULL_FRAME);
+    return ff;
+}
+
+COMMON_PORTABLE void __cilkrts_put_stack(full_frame *ff,
+                                         __cilkrts_stack_frame *sf)
+{
+    /* When suspending frame ff prior to stealing it, __cilkrts_put_stack is
+     * used to store the stack pointer for eventual sync.  When suspending
+     * frame ff prior to a sync, __cilkrts_put_stack is called to re-establish
+     * the sync stack pointer, offsetting it by any change in the stack depth
+     * that occured between the spawn and the sync.
+     * Although it is not usually meaningful to add two pointers, the value of
+     * ff->sync_sp at the time of this call is really an integer, not a
+     * pointer.
+     */
+    ptrdiff_t sync_sp_i = (ptrdiff_t) ff->sync_sp;
+    char* sp = (char*) __cilkrts_get_sp(sf);
+
+    ff->sync_sp = sp + sync_sp_i;
+
+    DBGPRINTF("%d-                __cilkrts_put_stack - adjust (+) sync "
+              "stack of full frame %p (+sp: %p) to %p\n",
+              __cilkrts_get_tls_worker()->self, ff, sp, ff->sync_sp);
+}
+
+COMMON_PORTABLE void __cilkrts_take_stack(full_frame *ff, void *sp)
+{
+    /* When resuming the parent after a steal, __cilkrts_take_stack is used to
+     * subtract the new stack pointer from the current stack pointer, storing
+     * the offset in ff->sync_sp.  When resuming after a sync,
+     * __cilkrts_take_stack is used to subtract the new stack pointer from
+     * itself, leaving ff->sync_sp at zero (null).  Although the pointers being
+     * subtracted are not part of the same contiguous chunk of memory, the
+     * flat memory model allows us to subtract them and get a useable offset.
+     */
+    ptrdiff_t sync_sp_i = ff->sync_sp - (char*) sp;
+
+    ff->sync_sp = (char *) sync_sp_i;
+
+    DBGPRINTF("%d-                __cilkrts_take_stack - adjust (-) sync "
+              "stack of full frame %p to %p (-sp: %p)\n",
+              __cilkrts_get_tls_worker()->self, ff, ff->sync_sp, sp);
+}
+
+COMMON_PORTABLE void __cilkrts_adjust_stack(full_frame *ff, size_t size)
+{
+    /* When resuming the parent after a steal, __cilkrts_take_stack is used to
+     * subtract the new stack pointer from the current stack pointer, storing
+     * the offset in ff->sync_sp.  When resuming after a sync,
+     * __cilkrts_take_stack is used to subtract the new stack pointer from
+     * itself, leaving ff->sync_sp at zero (null).  Although the pointers being
+     * subtracted are not part of the same contiguous chunk of memory, the
+     * flat memory model allows us to subtract them and get a useable offset.
+     *
+     * __cilkrts_adjust_stack() is used to deallocate a Variable Length Array
+     * by adding it's size to ff->sync_sp.
+     */
+    ff->sync_sp = ff->sync_sp + size;
+
+    DBGPRINTF("%d-                __cilkrts_adjust_stack - adjust (+) sync "
+              "stack of full frame %p to %p (+ size: 0x%x)\n",
+              __cilkrts_get_tls_worker()->self, ff, ff->sync_sp, size);
+}
+
+COMMON_PORTABLE
+void __cilkrts_destroy_full_frame(__cilkrts_worker *w, full_frame *ff)
+{
+    validate_full_frame(ff);
+    CILK_ASSERT(ff->children_reducer_map == 0);
+    CILK_ASSERT(ff->right_reducer_map == 0);
+    CILK_ASSERT(NULL == ff->pending_exception);
+    CILK_ASSERT(NULL == ff->child_pending_exception);
+    CILK_ASSERT(NULL == ff->right_pending_exception);
+    __cilkrts_mutex_destroy(w, &ff->lock);
+    __cilkrts_frame_free(w, ff, sizeof(*ff));
+}
+
+COMMON_PORTABLE void validate_full_frame(full_frame *ff)
+{
+    /* check the magic numbers, for debugging purposes */
+    if (ff->full_frame_magic_0 != FULL_FRAME_MAGIC_0 ||
+        ff->full_frame_magic_1 != FULL_FRAME_MAGIC_1)
+        abort_because_rts_is_corrupted();
+}
+
+void __cilkrts_frame_lock(__cilkrts_worker *w, full_frame *ff)
+{
+    validate_full_frame(ff);
+    __cilkrts_mutex_lock(w, &ff->lock);
+}
+
+void __cilkrts_frame_unlock(__cilkrts_worker *w, full_frame *ff)
+{
+    __cilkrts_mutex_unlock(w, &ff->lock);
+}
+
+/* End full_frame.c */
diff --git a/libcilkrts/runtime/full_frame.h b/libcilkrts/runtime/full_frame.h
new file mode 100644 (file)
index 0000000..327a333
--- /dev/null
@@ -0,0 +1,493 @@
+/* full_frame.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#ifndef INCLUDED_FULL_FRAME_DOT_H
+#define INCLUDED_FULL_FRAME_DOT_H
+
+
+#include "rts-common.h"
+#include "worker_mutex.h"
+
+#include <cilk/common.h>
+#include <internal/abi.h>
+#include <stddef.h>
+#include "cilk_fiber.h"
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/** Magic numbers for full_frame, used for debugging */
+typedef unsigned long long ff_magic_t;
+
+/* COMMON_SYSDEP */ struct pending_exception_info;  /* opaque */
+
+/*************************************************************
+  Full frames
+*************************************************************/
+
+/**
+ * @file full_frame.h
+ * @brief A full frame includes additional information such as a join
+ * counter and parent frame.
+ * @defgroup FullFrames Full Frames
+ * A full frame includes additional information such as a join
+ * counter and parent frame.
+ * @{
+ */
+
+/**
+ * Convenience typedef so we don't have to specify "struct full_frame"
+ * all over the code.  Putting it before the structure definition allows
+ * us to use the typedef within the structure itself
+ */
+typedef struct full_frame full_frame;
+
+/**
+ * @brief A full frame includes additional information such as a join
+ * counter and parent frame.
+ *
+ * The frame at the top of a worker's stack is promoted into a "full"
+ * frame, which carries additional information, such as join counter
+ * and parent frame.  Full frames can be suspended at a sync, in which
+ * case they lie somewhere in memory and do not belong to any
+ * worker. 
+ *
+ * Full frames are in contrast to the entries in the worker's deque which
+ * are only represented by a pointer to their __cilkrts_stack_frame.
+ *
+ * At any instant, we say that a full frame ff is either "suspended",
+ * or "owned" by some worker w.
+ *
+ * More precisely, we say that a worker w owns a frame ff under one of
+ * the following conditions:
+ *
+ *  1. Creation: Worker w has just created ff, but not yet linked ff
+ *     into the tree of full frames.  This situation can occur when a
+ *     worker is unrolling a call stack to promote a
+ *     __cilkrts_stack_frame to a full_frame.
+ *  2. Executing frame: We have w->l->frame_ff == ff, i.e,. ff is the
+ *     currently executing frame for w.
+ *  3. Next frame: We have w->l->next_frame_ff == ff, i.e,. ff is the
+ *     next frame that w is about to execute.
+ *  4. Resume execution: Worker w has popped ff from
+ *     w->l->next_frame_ff, and is about to resume execution of ff.
+ *  5. Dying leaf: Worker w has finished executing a frame ff
+ *     that is a leaf the tree of full frames, and is in the process
+ *     of unlinking "ff" from the tree.
+ *
+ * Otherwise, the frame ff is suspended, and has no owner.
+ * Note that work-stealing changes the owner of a full frame from the
+ * victim to the thief.  
+ *
+ * Using this notion of ownership, we classify the fields of a full
+ * frame into one of several categories:
+ *
+ *  1. Local: 
+ *     These fields are accessed only by the owner of the full frame.
+ *     Because a frame can have only one owner at a time, these fields
+ *     can be modified without any (additional) locking or
+ *     synchronization, assuming the correct synchronization for
+ *     changing the ownership of full frame (e.g., on a successful
+ *     steal) is already in place.
+ *
+ *  2. Constant (i.e., read-only):
+ *     This field is constant for the lifetime of the full frame.
+ *     No locks are needed to access this field.
+ *     Technically, a field could be read-only and local, but we assume
+ *     it is shared.
+ *  
+ *  3. Self-locked:
+ *     To access this field in the frame ff, a worker should acquire
+ *     the lock on ff.  
+ *     A self-locked field is conceptually "shared" between the worker
+ *     that owns frame ff (which is a child) and the worker that
+ *     owns the frame ff->parent (which is the parent of ff).
+ *
+ *  4. Parent-locked:
+ *     To access this field in the frame ff, a worker should
+ *     acquire the lock on ff->parent.
+ *     A parent-locked field is conceptually "shared" between the worker
+ *     that owns frame ff, and a worker that is either owns the
+ *     parent frame (ff->parent) or owns a sibling frame of ff (i.e.,
+ *     any child of ff->parent).
+ *
+ *  5. Synchronization
+ *     A field used explicitly for synchronization (i.e., locks).
+ */
+
+/* COMMON_PORTABLE */ 
+struct full_frame
+{
+    /**
+     * Value to detect writes off the beginning of a full_frame.
+     */
+#   define FULL_FRAME_MAGIC_0 ((ff_magic_t)0x361e710b9597d553ULL)
+
+    /**
+     * Field to detect writes off the beginning of a full_frame.  Must be
+     * FULL_FRAME_MAGIC_0.
+     * [constant]
+     */
+    ff_magic_t full_frame_magic_0;
+
+    /**
+     * Used to serialize access to this full_frame
+     * [synchronization]
+     */
+    struct mutex lock;
+
+    /**
+     * Count of outstanding children running in parallel
+     * [self-locked]
+     */
+    int join_counter;
+
+    /**
+     * If TRUE: frame was called by the parent.
+     * If FALSE: frame was spawned by parent.
+     * [constant]
+     */
+    int is_call_child;
+
+    /**
+     * TRUE if this frame is the loot of a simulated steal.
+     *
+     * This situation never happens in normal execution.  However,
+     * when running under cilkscreen, a worker may promote frames and
+     * then immediately suspend them, in order to simulate an
+     * execution on an infinite number of processors where all spawns
+     * are stolen.  In this case, the frame is marked as the loot of a fake
+     * steal.
+     * [local]
+     */
+    int simulated_stolen;
+
+    /**
+     * Caller of this full_frame
+     * [constant]
+     */
+    full_frame *parent;
+
+    /**
+     * Doubly-linked list of children.  The serial execution order is
+     * by definition from left to right.  Because of how we do work
+     * stealing, the parent is always to the right of all its
+     * children.
+     *
+     * For a frame ff, we lock the ff->parent to follow the sibling
+     * links for ff.
+     *
+     * [parent-locked]
+     */
+    full_frame *left_sibling;
+
+    /**
+     * @copydoc left_sibling
+     */
+    full_frame *right_sibling;
+
+    /**
+     * Pointer to rightmost child
+     *
+     * [self-locked]
+     */
+    full_frame *rightmost_child;
+
+    /**
+     * Call stack associated with this frame.
+     * Set and reset in make_unrunnable and make_runnable
+     *
+     * [self-locked]
+     */
+    __cilkrts_stack_frame *call_stack;
+
+    /**
+     * Accumulated reducers of children
+     *
+     * [self-locked]
+     */
+    struct cilkred_map *children_reducer_map;
+
+    /**
+     * Accumulated reducers of right siblings that have already
+     * terminated
+     *
+     * [parent-locked]
+     */
+    struct cilkred_map *right_reducer_map;
+
+    /**
+     * Exception that needs to be pass to our parent
+     *
+     * [local]
+     *
+     * TBD: verify that the exception code satisfies this requirement.
+     */
+    struct pending_exception_info *pending_exception;
+
+    /**
+     * Exception from one of our children
+     *
+     * [self-locked]
+     */
+    struct pending_exception_info *child_pending_exception;
+
+    /**
+     * Exception from any right siblings
+     *
+     * [parent-locked]
+     */
+    struct pending_exception_info *right_pending_exception;
+
+    /**
+     * Stack pointer to restore on sync.
+     * [local]
+     */
+    char *sync_sp;
+
+#ifdef _WIN32
+    /**
+     * Stack pointer to restore on exception.
+     * [local]
+     */
+    char *exception_sp;
+
+    /**
+     * Exception trylevel at steal
+     * [local]
+     *
+     * TBD: this field is set but not read?
+     */
+    unsigned long trylevel;
+
+    /**
+     * Exception registration head pointer to restore on sync.
+     * [local]
+     */
+    unsigned long registration;
+#endif
+
+    /**
+     * Size of frame to match sync sp
+     * [local]
+     * TBD: obsolete field only used in debugging?
+     */
+    ptrdiff_t frame_size;
+
+    /**
+     * Allocated fibers that need to be freed.  The fibers work
+     * like a reducer.  The leftmost frame may have @c fiber_self
+     * null and owner non-null.
+     *
+     * [local]
+     * TBD: verify exception code satisfies this requirement.
+     */
+    cilk_fiber *fiber_self;
+
+    /**
+     * Allocated fibers that need to be freed.  The fibers work
+     * like a reducer.  The leftmost frame may have @c fiber_self
+     * null and owner non-null.
+     *
+     * [self-locked]
+     */
+    cilk_fiber *fiber_child;
+
+    /**
+     * If the sync_master is set, this function can only be sync'd by the team
+     * leader, who first entered Cilk.  This is set by the first worker to steal
+     * from the user worker.
+     *
+     * [self-locked]
+     */
+    __cilkrts_worker *sync_master;
+
+    /**
+     * Value to detect writes off the end of a full_frame.
+     */
+#   define FULL_FRAME_MAGIC_1 ((ff_magic_t)0x189986dcc7aee1caULL)
+
+    /**
+     * Field to detect writes off the end of a full_frame.  Must be
+     * FULL_FRAME_MAGIC_1.
+     *
+     * [constant]
+     */
+    ff_magic_t full_frame_magic_1;
+};
+
+/* The functions __cilkrts_put_stack and __cilkrts_take_stack keep track of
+ * changes in the stack's depth between when the point at which a frame is
+ * stolen and when it is resumed at a sync.  A stolen frame typically goes
+ * through the following phase changes:
+ *
+ *   1. Suspend frame while stealing it.
+ *   2. Resume stolen frame at begining of continuation
+ *   3. Suspend stolen frame at a sync
+ *   4. Resume frame (no longer marked stolen) after the sync
+ *
+ * When the frame is suspended (steps 1 and 3), __cilkrts_put_stack is called to
+ * establish the stack pointer for the sync.  When the frame is resumed (steps
+ * 2 and 4), __cilkrts_take_stack is called to indicate the stack pointer
+ * (which may be on a different stack) at
+ * the point of resume.  If the stack pointer changes between steps 2 and 3,
+ * e.g., as a result of pushing 4 bytes onto the stack,
+ * the offset is reflected in the value of ff->sync_sp after step 3 relative to
+ * its value after step 1 (e.g., the value of ff->sync_sp after step 3 would be
+ * 4 less than its value after step 1, for a down-growing stack).
+ *
+ * Imp detail: The actual call chains for each of these phase-change events is:
+ *
+ *   1. unroll_call_stack -> make_unrunnable  -> __cilkrts_put_stack
+ *   2. do_work           -> __cilkrts_resume -> __cilkrts_take_stack
+ *   3. do_sync -> disown -> make_runnable    -> __cilkrts_put_stack
+ *   4. __cilkrts_resume                      -> __cilkrts_take_stack
+ *
+ * (The above is a changeable implementation detail.  The resume, sequence, in
+ * particular, is more complex on some operating systems.)
+ */
+
+/**
+ * @brief Records the stack pointer within the @c sf stack frame as the
+ * current stack pointer at the point of suspending full frame @c ff.
+ *
+ * @pre @c ff->sync_sp must be either null or contain the result of a prior call to
+ *      @c __cilkrts_take_stack().
+ * @pre If @c ff->sync_sp is not null, then @c SP(sf) must refer to the same stack as
+ *      the @c sp argument to the prior call to @c __cilkrts_take_stack().
+ * 
+
+ * @post If @c ff->sync_sp was null before the call, then @c
+ *       ff->sync_sp will be set to @c SP(sf).
+ * @post Otherwise, @c ff->sync_sp will be restored to the value it had just prior
+ *       to the last call to @c __cilkrts_take_stack(), except offset by any change
+ *       in the stack pointer between the call to @c __cilkrts_take_stack() and
+ *       this call to @c __cilkrts_put_stack().
+ *
+ * @param ff The full frame that is being suspended.
+ * @param sf The @c __cilkrts_stack_frame that is being suspended.  The stack
+ *   pointer will be taken from the jmpbuf contained within this
+ *   @c __cilkrts_stack_frame.
+ */
+COMMON_PORTABLE void __cilkrts_put_stack(full_frame *ff,
+                                         __cilkrts_stack_frame *sf);
+
+/**
+ * @brief Records the stack pointer @c sp as the stack pointer at the point of
+ * resuming execution on full frame @c ff.
+ *
+ * The value of @c sp may be on a different stack than the original
+ * value recorded for the stack pointer using __cilkrts_put_stack().
+ *
+ * @pre  @c ff->sync_sp must contain a value set by @c __cilkrts_put_stack().
+ *
+ * @post @c ff->sync_sp contains an *integer* value used to compute a change in the
+ *       stack pointer upon the next call to @c __cilkrts_take_stack().
+ * @post If @c sp equals @c ff->sync_sp, then @c ff->sync_sp is set to null.
+ *
+ * @param ff The full frame that is being resumed.
+ * @param sp The stack pointer for the stack the function is being resumed on.
+ */
+COMMON_PORTABLE void __cilkrts_take_stack(full_frame *ff, void *sp);
+
+/*
+ * @brief Adjust the stack for to deallocate a Variable Length Array
+ *
+ * @param ff The full frame that is being adjusted.
+ * @param size The size of the array being deallocated from the stack
+ */
+COMMON_PORTABLE void __cilkrts_adjust_stack(full_frame *ff, size_t size);
+
+/**
+ * @brief Allocates and initailizes a full_frame.
+ *
+ * @param w The memory for the full_frame will be allocated out of the
+ * worker's pool.
+ * @param sf The @c __cilkrts_stack_frame which will be saved as the call_stack
+ * for this full_frame.
+ *
+ * @return The newly allocated and initialized full_frame.
+ */
+COMMON_PORTABLE
+full_frame *__cilkrts_make_full_frame(__cilkrts_worker *w,
+                                      __cilkrts_stack_frame *sf);
+
+/**
+ * @brief Deallocates a full_frame.
+ *
+ * @param w The memory for the full_frame will be returned to the worker's pool.
+ * @param ff The full_frame to be deallocated.
+ */
+COMMON_PORTABLE
+void __cilkrts_destroy_full_frame(__cilkrts_worker *w, full_frame *ff);
+
+/**
+ * @brief Performs sanity checks to check the integrity of a full_frame.
+ *
+ * @param ff The full_frame to be validated.
+ */
+COMMON_PORTABLE void validate_full_frame(full_frame *ff);
+
+/**
+ * @brief Locks the mutex contained in a full_frame.
+ *
+ * The full_frame is validated before the runtime attempts to lock it.
+ *
+ * @post @c ff->lock will be owned by @c w.
+ *
+ * @param w  The worker that will own the full_frame.  If the runtime is
+ * collecting stats, the intervals will be attributed to the worker.
+ * @param ff The full_frame containing the mutex to be locked.
+ */
+COMMON_PORTABLE void __cilkrts_frame_lock(__cilkrts_worker *w,
+                                          full_frame *ff);
+
+/**
+ * @brief Unlocks the mutex contained in a full_frame.
+ *
+ * @pre @c ff->lock must must be owned by @c w.
+ *
+ * @param w  The worker that currently owns the full_frame.
+ * @param ff The full_frame containing the mutex to be unlocked.
+ */
+COMMON_PORTABLE void __cilkrts_frame_unlock(__cilkrts_worker *w,
+                                            full_frame *ff);
+/** @} */
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_FULL_FRAME_DOT_H)
diff --git a/libcilkrts/runtime/global_state.cpp b/libcilkrts/runtime/global_state.cpp
new file mode 100644 (file)
index 0000000..02de54f
--- /dev/null
@@ -0,0 +1,628 @@
+/* global_state.cpp                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#include "global_state.h"
+#include "os.h"
+#include "bug.h"
+#include "metacall_impl.h"
+#include "stats.h"
+#include "cilk/cilk_api.h"
+#include "cilk_malloc.h"
+#include "record-replay.h"
+
+#include <algorithm>  // For max()
+#include <cstring>
+#include <cstdlib>
+#include <climits>
+#include <cerrno>
+
+#ifdef _WIN32
+#   include <wchar.h>
+#endif
+
+// TBD: There is a race when multiple threads try to initialize the
+// user_settable_values??
+// 
+// Set to true if the user settable values portion of the global state
+// singleton is initialized, even if the rest of the singleton is not
+// initialized.
+int cilkg_user_settable_values_initialized = false;
+
+namespace {
+
+// Single copy of the global state.  Zero-filled until
+// cilkg_get_user_settable_values() is called and partially-zero-filled until
+// cilkg_init_global_state() is called.  The first field is filled in with
+// the size of a void* for the debugger and must be valid before initialization
+global_state_t global_state_singleton =
+{
+    sizeof(void *),    // addr_size
+};
+
+
+// Variables that need to export C-style names
+extern "C"
+{
+    // Pointer to the global state singleton.  
+    global_state_t *cilkg_singleton_ptr = NULL;
+
+    // __cilkrts_global_state is exported and referenced by the debugger.
+    // The debugger expects it to be valid when the module loads.
+//    CILK_EXPORT_DATA
+    global_state_t *__cilkrts_global_state = &global_state_singleton;
+}
+
+// Returns true if 'a' and 'b' are equal null-terminated strings
+inline bool strmatch(const char* a, const char* b)
+{
+    return 0 == std::strcmp(a, b);
+}
+
+// Returns the integer value represented by the null-terminated string at 's'.
+inline long to_long(const char* s)
+{
+    char *end;
+
+    errno = 0;
+    return std::strtol(s, &end, 0);
+}
+
+#ifdef _WIN32
+// Returns true if 'a' and 'b' are equal null-terminated wide-char strings
+inline bool strmatch(const wchar_t* a, const wchar_t* b)
+{
+    return 0 == wcscmp(a, b);
+}
+
+// Returns true if the multi-byte character string at 'a' represents the same
+// character sequence as the wide-character string at 'b'.  The behavior is
+// undefined if 'a' contains more than 30 multi-byte characters.
+bool strmatch(const char* a, const wchar_t* b)
+{
+    // Convert 'a' to wide-characters, then compare.
+    wchar_t wa[31];
+    std::size_t count;
+    errno_t err = mbstowcs_s(&count, wa, a, 30);
+    CILK_ASSERT(0 == err);
+    if (err) return false;
+    return strmatch(wa, b);
+}
+
+// Returns true if the wide-character string at 'a' represents the same
+// character sequence as the multi-byte character string at 'b'.  The behavior
+// id undefined if 'b' contains more than 30 multi-byte characters.
+inline
+bool strmatch(const wchar_t* a, const char* b)
+{
+    return strmatch(b, a);
+}
+
+
+// Returns the integer value represented by the null-terminated wide-char
+// string at 's'.
+inline long to_long(const wchar_t* s)
+{
+    wchar_t *end;
+
+    errno = 0;
+    return wcstol(s, &end, 0);
+}
+#endif
+
+// Check if Cilkscreen or other sequential ptool wants to force reducers.
+bool always_force_reduce()
+{
+    // Metacall *looks* like a no-op.  volatile needed to keep compiler from
+    // optimizing away variable.
+    volatile char not_force_reduce = '\377';
+    __cilkrts_metacall(METACALL_TOOL_SYSTEM, HYPER_ZERO_IF_FORCE_REDUCE,
+                       const_cast<char*>(&not_force_reduce));
+    return ! not_force_reduce;
+}
+
+// Stores the boolean value represented by the null-terminated string at 'val'
+// into the integer object at 'out'.  Returns '__CILKRTS_SET_PARAM_SUCCESS' if
+// 'val' is "true", "false", "0" or "1" and '__CILKRTS_SET_PARAM_INVALID'
+// otherwise.
+template <typename INT_T, typename CHAR_T>
+int store_bool(INT_T *out, const CHAR_T *val)
+{
+    static const char* const s_zero  = "0";
+    static const char* const s_one   = "1";
+    static const char* const s_true  = "true";
+    static const char* const s_false = "false";
+    
+    if (val == 0)
+        return __CILKRTS_SET_PARAM_INVALID;
+
+    if (strmatch(s_false, val) || strmatch(s_zero, val)) { 
+        *out = 0;
+        return __CILKRTS_SET_PARAM_SUCCESS;
+    }
+
+    if (strmatch(s_true, val) || strmatch(s_one, val)) { 
+        *out = 1;
+        return __CILKRTS_SET_PARAM_SUCCESS;
+    }
+
+    return __CILKRTS_SET_PARAM_INVALID;
+}
+
+// Stores the integer value represented by the null-terminated string at 'val'
+// into the integer object at 'out', restricting the result to the range 'min'
+// to 'max', inclusive.  Returns '__CILKRTS_SET_PARAM_SUCCESS' if the conversion
+// succeeds and is in range, '__CILKRTS_SET_PARAM_XRANGE' if the conversion
+// succeeds but is out of range, and '__CILKRTS_SET_PARAM_INVALID' otherwise.  In
+// the case of any error, '*out' is unchanged.
+template <typename INT_T, typename CHAR_T>
+int store_int(INT_T *out, const CHAR_T *val, INT_T min, INT_T max)
+{
+    errno = 0;
+    long val_as_long = to_long(val);
+    if (val_as_long == 0 && errno != 0)
+        return __CILKRTS_SET_PARAM_INVALID;
+    if (val_as_long < min || val_as_long == LONG_MIN)
+        return __CILKRTS_SET_PARAM_XRANGE;
+    else if (val_as_long > max || val_as_long == LONG_MAX)
+        return __CILKRTS_SET_PARAM_XRANGE;
+
+    *out = val_as_long;
+    return __CILKRTS_SET_PARAM_SUCCESS;
+}
+
+// Implementaton of cilkg_set_param templatized on character type.
+// Windows will instantiate with both char and wchar_t.
+// Note that g must have its user settable values set, but need not be fully
+// initialized.
+template <class CHAR_T>
+int set_param_imp(global_state_t* g, const CHAR_T* param, const CHAR_T* value)
+{
+    static const char* const s_force_reduce     = "force reduce";
+    static const char* const s_nworkers         = "nworkers";
+    static const char* const s_max_user_workers = "max user workers";
+    static const char* const s_local_stacks     = "local stacks";
+    static const char* const s_shared_stacks    = "shared stacks";
+    static const char* const s_nstacks          = "nstacks";
+    static const char* const s_stack_size       = "stack size";
+
+    // We must have a parameter and a value
+    if (0 == param)
+        return __CILKRTS_SET_PARAM_INVALID;
+    if (0 == value)
+        return __CILKRTS_SET_PARAM_INVALID;
+
+    if (strmatch(param, s_force_reduce))
+    {
+        // Sets whether we force a reduce operation at every sync.  Useful for
+        // debugging reducers.  Off by default.  Overridden by Cilkscreen
+        //
+        // Documented in cilk_api_<os>.h
+        if (always_force_reduce())
+            // Force reduce is set by cilkscreen.  User cannot change it.
+            return __CILKRTS_SET_PARAM_LATE;
+
+        return store_bool(&g->force_reduce, value);
+    }
+    else if (strmatch(param, s_nworkers))
+    {
+        // Set the total number of workers.  Overrides count of cores we get
+        // from the OS and the setting of the CILK_NWORKERS environment
+        // variable.  Setting to 0 indicates that the default worker count
+        // should be used.
+        //
+        // Documented in cilk_api_<os>.h
+        if (cilkg_singleton_ptr)
+            return __CILKRTS_SET_PARAM_LATE;
+
+        // Fetch the number of cores.  There must be at last 1, since we're
+        // executing on *something*, aren't we!?
+        int hardware_cpu_count = __cilkrts_hardware_cpu_count();
+        CILK_ASSERT(hardware_cpu_count > 0);
+
+        int max_cpu_count = 16 * hardware_cpu_count;
+        if (__cilkrts_running_under_sequential_ptool())
+        {
+            hardware_cpu_count = 1;
+            max_cpu_count = 1;
+        }
+        // Allow a value of 0, which means "set to hardware thread count".
+        int ret = store_int(&g->P, value, 0, max_cpu_count);
+        if (0 == g->P)
+            g->P = hardware_cpu_count;
+        return ret;
+    }
+    else if (strmatch(param, s_max_user_workers))
+    {
+        // ** UNDOCUMENTED **
+        //
+        // Sets the number of slots allocated for user worker threads
+        int hardware_cpu_count = __cilkrts_hardware_cpu_count();
+        CILK_ASSERT (hardware_cpu_count > 0);
+
+        return store_int(&g->max_user_workers, value, 1,
+                         16 * hardware_cpu_count);
+    }
+    else if (strmatch(param, s_local_stacks))
+    {
+        // ** UNDOCUMENTED **
+        //
+        // Number of stacks we'll hold in the per-worker stack cache.  Maximum
+        // value is 42.  See __cilkrts_make_global_state for details.
+        return store_int(&g->fiber_pool_size, value, 0, 42);
+    }
+    else if (strmatch(param, s_shared_stacks))
+    {
+        // ** UNDOCUMENTED **
+        //
+        // Maximum number of stacks we'll hold in the global stack
+        // cache. Maximum value is 42.  See __cilkrts_make_global_state for
+        // details.
+        return store_int(&g->global_fiber_pool_size, value, 0, 42);
+    }
+    else if (strmatch(param, s_nstacks))
+    {
+        // Sets the maximum number of stacks permitted at one time.  If the
+        // runtime reaches this maximum, it will cease to allocate stacks and
+        // the app will lose parallelism.  0 means unlimited.  Default is
+        // unlimited.  Minimum is twice the number of worker threads, though
+        // that cannot be tested at this time.
+        //
+        // Undocumented at this time, though there are plans to expose it.
+        // The current implentation is for Linux debugging only and is not
+        // robust enough for users.
+        if (cilkg_singleton_ptr)
+            return __CILKRTS_SET_PARAM_LATE;
+        return store_int<unsigned>(&g->max_stacks, value, 0, INT_MAX);
+    }
+    else if (strmatch(param, s_stack_size))
+    {
+        // ** UNDOCUMENTED **
+        //
+        // Sets the size (in bytes) of the stacks that Cilk creates.
+        // Can only be set before the runtime starts.
+        if (cilkg_singleton_ptr)
+            return __CILKRTS_SET_PARAM_LATE;
+
+        // Maximum value that can be parsed is MAX_INT (32-bit).
+        int ret = store_int<size_t>(&g->stack_size, value, 0, INT_MAX);
+
+        // Process the value the user set (or 0 if the user didn't set
+        // anything) into something nice for the current OS.  This
+        // processing is done immediately and stored into
+        // g->stack_size so that a call to get stack size will return
+        // the value that the runtime will actually use.
+        g->stack_size = cilkos_validate_stack_size(g->stack_size);
+        return ret;     
+    }
+
+
+    // If got here, then didn't match any of the strings
+    return __CILKRTS_SET_PARAM_UNIMP;
+}
+
+inline
+int calc_max_user_workers(global_state_t *g)
+{
+    // If it's been set by the user, give back what we got
+    if (g->max_user_workers > 0)
+        return g->max_user_workers;
+
+    // Calculate it
+    return std::max(3, g->P * 2);
+}
+
+} // end unnamed namespace
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * @brief Returns the global state object.  If called for the first time,
+ * initializes the user-settable values in the global state, but does not
+ * initialize the rest of the structure.
+ */
+global_state_t* cilkg_get_user_settable_values()
+{
+    // Environment variable value.  More than big enough for a 64-bit signed
+    // integer.
+    char envstr[24];
+
+    // Abbreviating &global_state_singleton as g is not only shorter, it also
+    // facilitates grepping for the string "g->", which appears ubiquitously
+    // in the runtime code.
+    global_state_t* g = &global_state_singleton;
+
+    // TBD: We need synchronization around this loop to prevent
+    // multiple threads from initializing this data.
+    if (! cilkg_user_settable_values_initialized)
+    {
+        size_t len;
+
+        // Preserve stealing disabled since it may have been set by the
+        // debugger
+        int stealing_disabled = g->stealing_disabled;
+
+        // All fields will be zero until set.  In particular
+        std::memset(g, 0, sizeof(global_state_t));
+
+        // Fetch the number of cores.  There must be at last 1, since we're
+        // executing on *something*, aren't we!?
+        int hardware_cpu_count = __cilkrts_hardware_cpu_count();
+        CILK_ASSERT(hardware_cpu_count > 0);
+
+        bool under_ptool = __cilkrts_running_under_sequential_ptool();
+        if (under_ptool)
+            hardware_cpu_count = 1;
+
+        g->stealing_disabled        = stealing_disabled;
+        g->under_ptool              = under_ptool;
+        g->force_reduce             = 0;   // Default Off
+        g->P                        = hardware_cpu_count;   // Defaults to hardware CPU count
+        g->max_user_workers         = 0;   // 0 unless set by user
+        g->fiber_pool_size          = 7;   // Arbitrary default
+        
+        g->global_fiber_pool_size   = 3 * 3* g->P;  // Arbitrary default
+        // 3*P was the default size of the worker array (including
+        // space for extra user workers).  This parameter was chosen
+        // to match previous versions of the runtime.
+
+        if (4 == sizeof(void *))
+            g->max_stacks           = 1200; // Only 1GB on 32-bit machines
+        else
+            g->max_stacks           = 2400; // 2GB on 64-bit machines
+
+        // If we have 2400 1MB stacks, that is 2 gb.  If we reach this
+        // limit on a single-socket machine, we may have other
+        // problems.  Is 2400 too small for large multicore machines?
+
+        // TBD(jsukha, 11/27/2012): I set this limit on stacks to be a
+        // value independent of P.  When running on a Xeon Phi with
+        // small values of P, I recall seeing a few microbenchmarks
+        // (e.g., fib) where a limit of 10*P seemed to be
+        // unnecessarily slowing things down.
+        // 
+        // That being said, the code has changed sufficiently that
+        // this observation may no longer be true.
+        //
+        // Note: in general, the worst-case number of stacks required
+        // for a Cilk computation with spawn depth "d" on P workers is
+        // O(Pd).  Code with unbalanced recursion may run into issues
+        // with this stack usage.
+
+        g->max_steal_failures       = 128; // TBD: depend on max_workers?
+        g->stack_size               = 0;   // 0 unless set by the user
+
+        // Assume no record or replay log for now
+        g->record_replay_file_name  = NULL;
+        g->record_or_replay         = RECORD_REPLAY_NONE;  // set by user
+
+        if (always_force_reduce())
+            g->force_reduce = true;
+        else if (cilkos_getenv(envstr, sizeof(envstr), "CILK_FORCE_REDUCE"))
+            store_bool(&g->force_reduce, envstr);
+
+        if (under_ptool)
+            g->P = 1;  // Ignore environment variable if under cilkscreen
+        else if (cilkos_getenv(envstr, sizeof(envstr), "CILK_NWORKERS"))
+            // Set P to environment variable, but limit to no less than 1
+            // and no more than 16 times the number of hardware threads.
+            store_int(&g->P, envstr, 1, 16 * hardware_cpu_count);
+
+        if (cilkos_getenv(envstr, sizeof(envstr), "CILK_MAX_USER_WORKERS"))
+            // Set max_user_workers to environment variable, but limit to no
+            // less than 1 and no more 16 times the number of hardware
+            // threads.  If not specified, defaults (somewhat arbitrarily) to
+            // the larger of 3 and twice the number of hardware threads.
+            store_int(&g->max_user_workers, envstr, 1, 16*hardware_cpu_count);
+
+        if (cilkos_getenv(envstr, sizeof(envstr), "CILK_STEAL_FAILURES"))
+            // Set the number of times a worker should fail to steal before
+            // it looks to see whether it should suspend itself.
+            store_int<unsigned>(&g->max_steal_failures, envstr, 1, INT_MAX);
+
+        // Compute the total number of workers to allocate.  Subtract one from
+        // nworkers and user workers so that the first user worker isn't
+        // factored in twice.
+        //
+        // total_workers must be computed now to support __cilkrts_get_total_workers
+        g->total_workers = g->P + calc_max_user_workers(g) - 1;
+
+#ifdef CILK_RECORD_REPLAY
+        // RecordReplay: See if we've been asked to replay a log
+        len = cilkos_getenv(envstr, 0, "CILK_REPLAY_LOG");
+        if (len > 0)
+        {
+            len += 1;    // Allow for trailing NUL
+            g->record_or_replay = REPLAY_LOG;
+            g->record_replay_file_name = (char *)__cilkrts_malloc(len);
+            cilkos_getenv(g->record_replay_file_name, len, "CILK_REPLAY_LOG");
+        }
+
+        // RecordReplay: See if we've been asked to record a log
+        len = cilkos_getenv(envstr, 0, "CILK_RECORD_LOG");
+        if (len > 0)
+        {
+            if (RECORD_REPLAY_NONE != g->record_or_replay)
+                cilkos_warning("CILK_RECORD_LOG ignored since CILK_REPLAY_LOG is defined.\n");
+            else
+            {
+                len += 1;    // Allow for trailing NUL
+                g->record_or_replay = RECORD_LOG;
+                g->record_replay_file_name = (char *)__cilkrts_malloc(len);
+                cilkos_getenv(g->record_replay_file_name, len, "CILK_RECORD_LOG");
+            }
+        }
+#endif
+        
+        cilkg_user_settable_values_initialized = true;
+    }
+
+    return g;
+}
+
+int cilkg_calc_total_workers()
+{
+    global_state_t* g = cilkg_get_user_settable_values();
+
+    // Compute the total number of workers to allocate.  Subtract one from
+    // nworkers and user workers so that the first user worker isn't
+    // factored in twice.
+    return g->P + calc_max_user_workers(g) - 1;
+}
+
+// Should be called while holding the global lock.
+global_state_t* cilkg_init_global_state()
+{
+    if (cilkg_singleton_ptr)
+        return cilkg_singleton_ptr;
+
+    // Get partially-initialized global state.
+    global_state_t* g = cilkg_get_user_settable_values();
+
+    if (g->max_stacks > 0) {
+
+        // nstacks is currently honored on non-Windows systems only.
+
+        // Set an upper bound on the number of stacks that are allocated.  If
+        // nstacks is set, each worker gets up to one stack in its cache so that
+        // no one worker can hog all of the free stacks and keep work from being
+        // stolen by the other workers.
+
+        // nstacks corresponds to the number of stacks that will be allocated by
+        // the runtime apart from the initial stack created for each thread by
+        // the system.  Therefore, if a user asks for n stacks, and there are
+        // p workers created, the total number of stacks is actually n + p.
+
+        // This feature is primarily for MIC which has flat memory
+        // instead of virtual addresses and tends to run out really quickly.
+        // It is not implemented for Windows and it's non-intuitive
+        // interaction with the local stack cache is specifically to help out
+        // MIC.
+
+        // About max_stacks / P stacks, except we require at least 1
+        // per pool.
+        if (((int)g->max_stacks / g->P) < g->fiber_pool_size)
+            g->fiber_pool_size = g->max_stacks / g->P;
+
+        if (g->fiber_pool_size <= 0) {
+            g->fiber_pool_size = 1;
+        }
+        
+        if ((int)g->max_stacks < g->P)
+            g->max_stacks = g->P;
+
+        g->global_fiber_pool_size = g->P * (g->fiber_pool_size+1);
+    }
+
+    // Number of bytes/address - validation for debugger integration
+    g->addr_size = sizeof(void *);
+
+    __cilkrts_init_stats(&g->stats);
+
+    __cilkrts_frame_malloc_global_init(g);
+
+    g->Q = 0;
+    g->total_workers = cilkg_calc_total_workers();
+    g->system_workers = g->P - 1; // system_workers is here for the debugger.
+    g->work_done = 0;
+    g->workers_running = 0;
+    g->ltqsize = 1024; /* FIXME */
+
+    g->stack_size = cilkos_validate_stack_size(g->stack_size);
+    g->failure_to_allocate_stack = 0;
+
+
+    return g;
+}
+
+void cilkg_publish_global_state(global_state_t* g) 
+{
+
+    // TBD: which one of these needs to be executed first?  I say
+    // cilkg_singleton_ptr needs to be set last, with a mfence in
+    // between, since it is the flag that cilkg_is_published_is
+    // checking for.
+    __cilkrts_global_state = g;
+    __cilkrts_fence();
+    cilkg_singleton_ptr = g;
+}
+
+void cilkg_deinit_global_state()
+{
+    cilkg_singleton_ptr = NULL;
+    __cilkrts_global_state = NULL;
+}
+
+int cilkg_is_published(void)
+{
+    return NULL != cilkg_singleton_ptr;
+}
+
+int cilkg_set_param(const char* param, const char* value)
+{
+    return set_param_imp(cilkg_get_user_settable_values(), param, value);
+}
+
+#ifdef _WIN32
+int cilkg_set_param_w(const wchar_t* param, const wchar_t* value)
+{
+    return set_param_imp(cilkg_get_user_settable_values(), param, value);
+}
+#endif
+
+extern "C++" {
+    // C++ scheduler function (that may throw exceptions)
+    typedef void cpp_scheduler_t(__cilkrts_worker *w);
+}
+
+void __cilkrts_run_scheduler_with_exceptions(__cilkrts_worker *w)
+{
+    global_state_t* g = cilkg_get_global_state();
+    CILK_ASSERT(g->scheduler);
+
+    cpp_scheduler_t* scheduler = (cpp_scheduler_t*) g->scheduler;
+
+    try {
+        scheduler(w);
+    } catch (...) {
+        __cilkrts_bug("Exception escaped Cilk context");
+    }
+}
+
+__CILKRTS_END_EXTERN_C
+
+/* End global_state.cpp */
diff --git a/libcilkrts/runtime/global_state.h b/libcilkrts/runtime/global_state.h
new file mode 100644 (file)
index 0000000..ef455e4
--- /dev/null
@@ -0,0 +1,417 @@
+/* global_state.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file global_state.h
+ *
+ * @brief The global_state_t structure contains most of the global context
+ * maintained by the Intel Cilk runtime.
+ */
+
+#ifndef INCLUDED_GLOBAL_STATE_DOT_H
+#define INCLUDED_GLOBAL_STATE_DOT_H
+
+#include <cilk/common.h>
+
+#include "frame_malloc.h"
+#include "stats.h"
+#include "bug.h"
+#include "cilk_fiber.h"
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * Non-null place-holder for a stack handle that has no meaningful value.
+ */
+#define PLACEHOLDER_FIBER  ((cilk_fiber *) -2)
+
+/**
+ * States for record_or_replay
+ */
+enum record_replay_t {
+    RECORD_REPLAY_NONE,
+    RECORD_LOG,
+    REPLAY_LOG
+};
+
+/**
+ * @brief The global state is a structure that is shared by all workers in
+ * Cilk.
+ *
+ * Make the structure ready for use by calling
+ * cilkg_init_global_state() and then cilkg_publish_global_state().
+ *
+ * The same global lock should be held while both of these methods are
+ * called.  These methods are split because it is useful to execute
+ * other runtime initialization code in between.
+ *
+ * After cilkg_publish_global_state() has completed, Cilk runtime
+ * methods may call cilkg_get_global_state() to look at the published
+ * value without holding the global lock.
+ *
+ * Finally, clean up the global state by calling
+ * cilkg_deinit_global_state().  This method should be called only
+ * after all calls to cilkg_get_global_state() have completed, and
+ * while holding the global lock.
+ *
+ * Before initialization and after deinitialization, the fields in the
+ * global state have unspecified values, except for a few special
+ * fields labeled "USER SETTING", which can be read and written before
+ * initialization and after deinitialization.
+ */
+
+struct global_state_t { /* COMMON_PORTABLE */
+
+    /* Fields described as "(fixed)" should not be changed after
+     * initialization.
+     */
+
+    /*************************************************************************
+     * Note that debugger integration must reach into the
+     * global state!  The debugger integration is depending on the
+     * offsets of the addr_size, system_workers, total_workers,
+     * stealing_disabled, sysdep, and workers.  If these offsets change, the
+     * debugger integration library will need to be changed to match!!!
+     *************************************************************************/
+
+    int addr_size; ///< Number of bytes for an address, used by debugger (fixed)
+
+    int system_workers; ///< Number of system workers (fixed)
+
+    /**
+     * @brief USER SETTING: Maximum number of user workers that can be
+     * bound to cilk workers.
+     *
+     * 0 unless set by user.  Call cilkg_calc_max_user_workers to get
+     * the value.
+     */
+    int max_user_workers; 
+
+    int total_workers;  ///< Total number of worker threads allocated (fixed)
+
+    int workers_running; ///< True when system workers have beens started */
+
+    /// Set by debugger to disable stealing (fixed)
+    int stealing_disabled;
+
+    /// System-dependent part of the global state
+    struct global_sysdep_state *sysdep;
+
+    /// Array of worker structures.
+    __cilkrts_worker **workers;
+
+    /******* END OF DEBUGGER-INTEGRATION FIELDS ***************/
+
+    /// Number of frames in each worker's lazy task queue
+    __STDNS size_t ltqsize;
+
+    /**
+     * @brief USER SETTING: Force all possible reductions.
+     *
+     * TRUE if running a p-tool that requires reducers to call the reduce()
+     * method even if no actual stealing occurs.
+     *
+     * When set to TRUE, runtime will simulate steals, forcing calls to the 
+     * the reduce() methods of reducers.
+     *
+     */
+    int force_reduce;    
+
+    /// USER SETTING: Per-worker fiber pool size
+    int fiber_pool_size; 
+
+    /// USER SETTING: Global fiber pool size
+    int global_fiber_pool_size;
+
+    /**
+     * @brief TRUE when workers should exit scheduling loop so we can
+     * shut down the runtime and free the global state.
+     *
+     * @note @c work_done will be checked *FREQUENTLY* in the scheduling loop
+     * by idle workers.  We need to ensure that it's not in a cache line which
+     * may be invalidated by other cores.  The surrounding fields are either
+     * constant after initialization or not used until shutdown (stats) so we
+     * should be OK.
+     */
+    volatile int work_done;
+
+    int under_ptool;     ///< True when running under a serial PIN tool
+
+    statistics stats;    ///< Statistics on use of runtime
+
+    /**
+     * @brief USER SETTING: Maximum number of stacks the runtime will
+     * allocate (apart from those created by the OS when worker
+     * threads are created).
+     *
+     * If max_stacks == 0,there is no pre-defined maximum.
+     */
+    unsigned max_stacks; 
+
+    /// Size of each stack
+    size_t stack_size;
+
+    /// Global cache for per-worker memory
+    struct __cilkrts_frame_cache frame_malloc;
+
+    /// Global fiber pool
+    cilk_fiber_pool fiber_pool;
+
+
+    /**
+     * @brief Track whether the runtime has failed to allocate a
+     * stack.
+     * 
+     * Setting this flag prevents multiple warnings from being
+     * issued.
+     */
+    int failure_to_allocate_stack;
+
+    /**
+     * @brief USER SETTING: indicate record or replay log.
+     * Set to NULL if not used in this run.
+     */
+    char *record_replay_file_name;
+
+    /**
+     * @brief Record/replay state.
+     * Valid states are:
+     *   RECORD_REPLAY_NONE - Not recording or replaying a log
+     *   RECORD_LOG - Recording a log for replay later
+     *   REPLAY_LOG - Replay a log recorded earlier
+     */
+    enum record_replay_t record_or_replay;
+
+    /**
+     * @brief Buffer to force max_steal_failures to appear on a
+     * different cache line from the previous member variables.
+     *
+     * This padding is needed because max_steal_failures is read
+     * constantly and other modified values in the global state will
+     * cause thrashing.
+     */
+    char cache_buf[64];
+
+    /**
+     * @brief Maximum number of times a thread should fail to steal
+     * before checking if Cilk is shutting down.
+     */
+    unsigned int max_steal_failures;
+
+    /// Pointer to scheduler entry point
+    void (*scheduler)(__cilkrts_worker *w);
+
+    /**
+     * @brief Buffer to force P and Q to appear on a different cache
+     * line from the previous member variables.
+     */
+    char cache_buf_2[64];
+
+    int P;         ///< USER SETTING: number of system workers + 1 (fixed)
+    int Q;         ///< Number of user threads currently bound to workers 
+};
+
+/**
+ * @brief Initialize the global state object.  This method must both
+ * complete before referencing any fields in the global state, except
+ * those specified as "user-settable values".
+ */
+global_state_t* cilkg_init_global_state();
+
+/**
+ * @brief Publish the global state object, so that
+ * cilkg_is_published can return true.
+ *
+ * @param g - the global state created by cilkg_init_global_state() to
+ * publish.
+ *
+ * After the global state object has been published, a thread should
+ * not modify this state unless it has exclusive access (i.e., holds
+ * the global lock).
+ */
+void cilkg_publish_global_state(global_state_t* g);
+
+/**
+ * @brief Return true if the global state has been fully initialized
+ * and published, and has not been deinitialized.
+ */
+int cilkg_is_published(void);
+
+/**
+ * @brief De-initializes the global state object.  Must be called to free
+ * resources when the global state is no longer needed.
+ */
+void cilkg_deinit_global_state(void);
+
+/**
+ * @brief Returns the global state object.  Result is valid only if the
+ * global state has been published (see cilkg_publish_global_state()).
+ */
+static inline
+global_state_t* cilkg_get_global_state(void)
+{
+    // "private" extern declaration:
+    extern global_state_t *cilkg_singleton_ptr;
+
+    __CILKRTS_ASSERT(cilkg_singleton_ptr); // Debug only
+    return cilkg_singleton_ptr;
+}
+
+
+/**
+ * @brief Implementation of __cilkrts_set_params.
+ *
+ * Set user controllable parameters
+ * @param param - string specifying parameter to be set
+ * @param value - string specifying new value
+ * @returns One of: CILKG_SET_PARAM_SUCCESS ( = 0),
+ *    CILKG_SET_PARAM_UNIMP, CILKG_SET_PARAM_XRANGE,
+ *    CILKG_SET_PARAM_INVALID, or CILKG_SET_PARAM_LATE.
+ *
+ * @attention The wide character version __cilkrts_set_param_w() is available
+ * only on Windows.
+ *
+ * Allowable parameter names:
+ *
+ * - "nworkers" - number of processors that should run Cilk code.
+ *   The value is a string of digits to be parsed by strtol.
+ *
+ * - "force reduce" - test reducer callbacks by allocating new views
+ *   for every spawn within which a reducer is accessed.  This can
+ *   significantly reduce performance.  The value is "1" or "true"
+ *   to enable, "0" or "false" to disable.
+ *   @warning Enabling "force reduce" when running with more than a single
+ *   worker is currently broken.
+ *
+ * - "max user workers" - (Not publicly documented) Sets the number of slots
+ *   allocated for user worker threads
+ *
+ * - "local stacks" - (Not publicly documented) Number of stacks we'll hold in
+ *   the per-worker stack cache.  Range 1 .. 42.  See
+ *   cilkg_init_global_state for details.
+ *
+ * - "shared stacks" - (Not publicly documented) Maximum number of stacks
+ *   we'll hold in the global stack cache. Maximum value is 42.  See
+ *   __cilkrts_make_global_state for details
+ *
+ * - "nstacks" - (Not publicly documented at this time, though it may be
+ *   exposed in the future) Sets the maximum number of stacks permitted at one
+ *   time.  If the runtime reaches this maximum, it will cease to allocate
+ *   stacks and the app will lose parallelism.  0 means unlimited.  Default is
+ *   unlimited.  Minimum is twice the number of worker threads, though that
+ *   cannot be tested at this time.
+ */
+int cilkg_set_param(const char* param, const char* value);
+#ifdef _WIN32
+/**
+ * @brief Implementation of __cilkrts_set_params for Unicode characters on
+ * Windows.  See the documentation on @ref cilkg_set_param for more details.
+ *
+ * Set user controllable parameters
+ * @param param - string specifying parameter to be set
+ * @param value - string specifying new value
+ * @returns One of: CILKG_SET_PARAM_SUCCESS ( = 0),
+ *    CILKG_SET_PARAM_UNIMP, CILKG_SET_PARAM_XRANGE,
+ *    CILKG_SET_PARAM_INVALID, or CILKG_SET_PARAM_LATE.
+ */
+int cilkg_set_param_w(const wchar_t* param, const wchar_t* value);
+#endif
+
+/**
+ * @brief implementation of __cilkrts_get_nworkers()
+ */
+static inline
+int cilkg_get_nworkers(void)
+{
+    // "private" extern declaration
+    extern global_state_t* cilkg_get_user_settable_values(void);
+    return cilkg_get_user_settable_values()->P;
+}
+
+/**
+ * @brief implementation of __cilkrts_get_total_workers()
+ */
+static inline
+int cilkg_get_total_workers(void)
+{
+    // "private" extern declaration
+    extern int cilkg_calc_total_workers(void);
+
+    // This number can fluctate until initialization so we
+    // compute it from scratch
+    return cilkg_calc_total_workers();
+}
+
+/**
+ * @brief implementation of __cilkrts_get_force_reduce()
+ */
+static inline
+int cilkg_get_force_reduce(void)
+{
+    // "private" extern declaration
+    extern global_state_t* cilkg_get_user_settable_values(void);
+    return cilkg_get_user_settable_values()->force_reduce;
+}
+
+/**
+ * @brief implementation of __cilkrts_get_stack_size()
+ */
+static inline
+size_t cilkg_get_stack_size(void)
+{
+    // "private" extern declaration
+    extern global_state_t* cilkg_get_user_settable_values(void);
+    return cilkg_get_user_settable_values()->stack_size;
+}
+
+/**
+ * @brief Run the scheduler function stored in the global_state
+ *
+ * Look up the scheduler function in global_state and run it.  Report a fatal
+ * error if an exception escapes the scheduler function.
+ * 
+ * @param w - Worker structure to associate with the current thread.
+ *
+ * @attention The scheduler field of the global state must be set before this
+ * function is called.
+ */
+void __cilkrts_run_scheduler_with_exceptions(__cilkrts_worker *w);
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_GLOBAL_STATE_DOT_H)
diff --git a/libcilkrts/runtime/jmpbuf.c b/libcilkrts/runtime/jmpbuf.c
new file mode 100644 (file)
index 0000000..39b51a5
--- /dev/null
@@ -0,0 +1,48 @@
+/* jmpbuf.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#include "jmpbuf.h"
+
+/*
+ * C99 requires that every inline function with external linkage have
+ * one extern declaration in the program.
+ */
+extern char *__cilkrts_get_sp(__cilkrts_stack_frame *sf);
+extern ptrdiff_t __cilkrts_get_frame_size(__cilkrts_stack_frame *sf);
+
+/* End jmpbuf.c */
diff --git a/libcilkrts/runtime/jmpbuf.h b/libcilkrts/runtime/jmpbuf.h
new file mode 100644 (file)
index 0000000..60573f3
--- /dev/null
@@ -0,0 +1,136 @@
+/* jmpbuf.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file jmpbuf.h
+ *
+ * @brief Macros and functions to access the _JUMP_BUFFER initialized by a 
+ * call to CILK_SETJMP before a cilk_spawn or cilk_sync.  The definition of
+ * CILK_SETJMP and CILK_LONGJMP are OS dependent and in abi.h
+ *
+ */
+
+#ifndef INCLUDED_JMPBUF_DOT_H
+#define INCLUDED_JMPBUF_DOT_H
+
+#include <cilk/common.h>
+#include <internal/abi.h>
+#include <stddef.h>
+#include <setjmp.h>
+
+#if 0 /* defined CILK_USE_C_SETJMP && defined JB_RSP */
+#   define JMPBUF_SP(ctx) (ctx)[0].__jmpbuf[JB_RSP]
+#   define JMPBUF_FP(ctx) (ctx)[0].__jmpbuf[JB_RBP]
+#   define JMPBUF_PC(ctx) (ctx)[0].__jmpbuf[JB_PC]
+#elif 0 /* defined CILK_USE_C_SETJMP && defined JB_SP */
+#   define JMPBUF_SP(ctx) (ctx)[0].__jmpbuf[JB_SP]
+#   define JMPBUF_FP(ctx) (ctx)[0].__jmpbuf[JB_BP]
+#   define JMPBUF_PC(ctx) (ctx)[0].__jmpbuf[JB_PC]
+#elif defined _WIN64
+#   define JMPBUF_SP(ctx) ((_JUMP_BUFFER*)(&(ctx)))->Rsp
+#   define JMPBUF_FP(ctx) ((_JUMP_BUFFER*)(&(ctx)))->Rbp
+#   define JMPBUF_PC(ctx) ((_JUMP_BUFFER*)(&(ctx)))->Rip
+#elif defined _WIN32
+    /** Fetch stack pointer from a __cilkrts_stack_frame */
+#   define JMPBUF_SP(ctx) (ctx).Esp
+    /** Fetch frame pointer from a __cilkrts_stack_frame */
+#   define JMPBUF_FP(ctx) (ctx).Ebp
+    /** Fetch program counter from a __cilkrts_stack_frame */
+#   define JMPBUF_PC(ctx) (ctx).Eip
+#else /* defined __GNUC__ || defined __ICC */
+    /* word 0 is frame address
+     * word 1 is resume address
+     * word 2 is stack address */
+#   define JMPBUF_FP(ctx) (ctx)[0]
+#   define JMPBUF_PC(ctx) (ctx)[1]
+#   define JMPBUF_SP(ctx) (ctx)[2]
+#endif
+
+/**
+ * @brief Get frame pointer from jump buffer in__cilkrts_stack_frame.
+ */
+#define FP(SF) JMPBUF_FP((SF)->ctx)
+
+/**
+ * @brief Get program counter from jump buffer in__cilkrts_stack_frame.
+ */
+#define PC(SF) JMPBUF_PC((SF)->ctx)
+
+/**
+ * @brief Get stack pointer from jump buffer in__cilkrts_stack_frame.
+ */
+#define SP(SF) JMPBUF_SP((SF)->ctx)
+
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * Fetch the stack pointer from a __cilkrts_stack_frame.  The jmpbuf was
+ * initialized before a cilk_spawn or cilk_sync.
+ *
+ * @param sf __cilkrts_stack_frame containing the jmpbuf.
+ *
+ * @return the stack pointer from the ctx.
+ */
+inline char *__cilkrts_get_sp(__cilkrts_stack_frame *sf)
+{
+    return (char *)SP(sf);
+}
+
+/**
+ * Calculate the frame size from __cilkrts_stack_frame.  The jmpbuf was
+ * initialized before a cilk_spawn or cilk_sync.
+ *
+ * @warning Returning an arbitrary value on Windows!
+ *
+ * @param sf __cilkrts_stack_frame containing the jmpbuf.
+ *
+ * @return the stack pointer from the ctx.
+ */
+inline ptrdiff_t __cilkrts_get_frame_size(__cilkrts_stack_frame *sf)
+{
+#ifdef _WIN32
+    if (0 == SP(sf))
+        return 256;         // Arbitrary!
+#endif
+    return (ptrdiff_t)FP(sf) - (ptrdiff_t)SP(sf);
+}
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_JMPBUF_DOT_H)
diff --git a/libcilkrts/runtime/linux-symbols.ver b/libcilkrts/runtime/linux-symbols.ver
new file mode 100644 (file)
index 0000000..aeb4a5f
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+CILKABI0
+{
+  global:
+    __cilkrts_bind_thread;
+    __cilkrts_cilk_for_32;
+    __cilkrts_cilk_for_64;
+    __cilkrts_debugger_notification;
+    __cilkrts_dump_stats;
+    __cilkrts_end_cilk;
+    __cilkrts_enter_frame;
+    __cilkrts_enter_frame_fast;
+    __cilkrts_get_force_reduce;
+    __cilkrts_get_nworkers;
+    __cilkrts_get_tls_worker;
+    __cilkrts_get_tls_worker_fast;
+    __cilkrts_get_total_workers;
+    __cilkrts_get_worker_number;
+    __cilkrts_global_state;
+    __cilkrts_hyper_create;
+    __cilkrts_hyper_destroy;
+    __cilkrts_hyper_lookup;
+    __cilkrts_hyperobject_alloc;
+    __cilkrts_hyperobject_dealloc;
+    __cilkrts_hyperobject_noop_destroy;
+    __cilkrts_init;
+    __cilkrts_irml_version;
+    __cilkrts_leave_frame;
+    __cilkrts_metacall;
+    __cilkrts_rethrow;
+    __cilkrts_return_exception;
+    __cilkrts_set_param;
+    __cilkrts_sync;
+    __cilkrts_synched;
+    __cilkrts_worker_stub;
+  local: *;
+};
+
+CILKABI1
+{
+  global:
+    __cilkrts_bind_thread_1;
+    __cilkrts_bump_loop_rank;
+    __cilkrts_bump_loop_rank_internal;
+    __cilkrts_bump_worker_rank;
+    __cilkrts_bump_worker_rank_internal;
+    __cilkrts_enter_frame_1;
+    __cilkrts_enter_frame_fast_1;
+    __cilkrts_get_pedigree_info;
+    __cilkrts_get_pedigree_internal;
+    __cilkrts_get_sf;
+    __cilkrts_get_stack_size;
+    __cilkrts_get_worker_rank;
+    __cilkrts_save_fp_ctrl_state;
+    __cilkrts_stack_alloc;
+    __cilkrts_stack_free;
+    __cilkrts_watch_stack;
+} CILKABI0;
+
+CILKLIB1.02
+{
+  global:
+    cilk_c_reducer_max_identity_char;
+    cilk_c_reducer_max_identity_double;
+    cilk_c_reducer_max_identity_float;
+    cilk_c_reducer_max_identity_int;
+    cilk_c_reducer_max_identity_long;
+    cilk_c_reducer_max_identity_longdouble;
+    cilk_c_reducer_max_identity_longlong;
+    cilk_c_reducer_max_identity_schar;
+    cilk_c_reducer_max_identity_short;
+    cilk_c_reducer_max_identity_uchar;
+    cilk_c_reducer_max_identity_uint;
+    cilk_c_reducer_max_identity_ulong;
+    cilk_c_reducer_max_identity_ulonglong;
+    cilk_c_reducer_max_identity_unsigned;
+    cilk_c_reducer_max_identity_ushort;
+    cilk_c_reducer_max_identity_wchar_t;
+    cilk_c_reducer_max_index_identity_char;
+    cilk_c_reducer_max_index_identity_double;
+    cilk_c_reducer_max_index_identity_float;
+    cilk_c_reducer_max_index_identity_int;
+    cilk_c_reducer_max_index_identity_long;
+    cilk_c_reducer_max_index_identity_longdouble;
+    cilk_c_reducer_max_index_identity_longlong;
+    cilk_c_reducer_max_index_identity_schar;
+    cilk_c_reducer_max_index_identity_short;
+    cilk_c_reducer_max_index_identity_uchar;
+    cilk_c_reducer_max_index_identity_uint;
+    cilk_c_reducer_max_index_identity_ulong;
+    cilk_c_reducer_max_index_identity_ulonglong;
+    cilk_c_reducer_max_index_identity_unsigned;
+    cilk_c_reducer_max_index_identity_ushort;
+    cilk_c_reducer_max_index_identity_wchar_t;
+    cilk_c_reducer_max_index_reduce_char;
+    cilk_c_reducer_max_index_reduce_double;
+    cilk_c_reducer_max_index_reduce_float;
+    cilk_c_reducer_max_index_reduce_int;
+    cilk_c_reducer_max_index_reduce_long;
+    cilk_c_reducer_max_index_reduce_longdouble;
+    cilk_c_reducer_max_index_reduce_longlong;
+    cilk_c_reducer_max_index_reduce_schar;
+    cilk_c_reducer_max_index_reduce_short;
+    cilk_c_reducer_max_index_reduce_uchar;
+    cilk_c_reducer_max_index_reduce_uint;
+    cilk_c_reducer_max_index_reduce_ulong;
+    cilk_c_reducer_max_index_reduce_ulonglong;
+    cilk_c_reducer_max_index_reduce_unsigned;
+    cilk_c_reducer_max_index_reduce_ushort;
+    cilk_c_reducer_max_index_reduce_wchar_t;
+    cilk_c_reducer_max_reduce_char;
+    cilk_c_reducer_max_reduce_double;
+    cilk_c_reducer_max_reduce_float;
+    cilk_c_reducer_max_reduce_int;
+    cilk_c_reducer_max_reduce_long;
+    cilk_c_reducer_max_reduce_longdouble;
+    cilk_c_reducer_max_reduce_longlong;
+    cilk_c_reducer_max_reduce_schar;
+    cilk_c_reducer_max_reduce_short;
+    cilk_c_reducer_max_reduce_uchar;
+    cilk_c_reducer_max_reduce_uint;
+    cilk_c_reducer_max_reduce_ulong;
+    cilk_c_reducer_max_reduce_ulonglong;
+    cilk_c_reducer_max_reduce_unsigned;
+    cilk_c_reducer_max_reduce_ushort;
+    cilk_c_reducer_max_reduce_wchar_t;
+    cilk_c_reducer_min_identity_char;
+    cilk_c_reducer_min_identity_double;
+    cilk_c_reducer_min_identity_float;
+    cilk_c_reducer_min_identity_int;
+    cilk_c_reducer_min_identity_long;
+    cilk_c_reducer_min_identity_longdouble;
+    cilk_c_reducer_min_identity_longlong;
+    cilk_c_reducer_min_identity_schar;
+    cilk_c_reducer_min_identity_short;
+    cilk_c_reducer_min_identity_uchar;
+    cilk_c_reducer_min_identity_uint;
+    cilk_c_reducer_min_identity_ulong;
+    cilk_c_reducer_min_identity_ulonglong;
+    cilk_c_reducer_min_identity_unsigned;
+    cilk_c_reducer_min_identity_ushort;
+    cilk_c_reducer_min_identity_wchar_t;
+    cilk_c_reducer_min_index_identity_char;
+    cilk_c_reducer_min_index_identity_double;
+    cilk_c_reducer_min_index_identity_float;
+    cilk_c_reducer_min_index_identity_int;
+    cilk_c_reducer_min_index_identity_long;
+    cilk_c_reducer_min_index_identity_longdouble;
+    cilk_c_reducer_min_index_identity_longlong;
+    cilk_c_reducer_min_index_identity_schar;
+    cilk_c_reducer_min_index_identity_short;
+    cilk_c_reducer_min_index_identity_uchar;
+    cilk_c_reducer_min_index_identity_uint;
+    cilk_c_reducer_min_index_identity_ulong;
+    cilk_c_reducer_min_index_identity_ulonglong;
+    cilk_c_reducer_min_index_identity_unsigned;
+    cilk_c_reducer_min_index_identity_ushort;
+    cilk_c_reducer_min_index_identity_wchar_t;
+    cilk_c_reducer_min_index_reduce_char;
+    cilk_c_reducer_min_index_reduce_double;
+    cilk_c_reducer_min_index_reduce_float;
+    cilk_c_reducer_min_index_reduce_int;
+    cilk_c_reducer_min_index_reduce_long;
+    cilk_c_reducer_min_index_reduce_longdouble;
+    cilk_c_reducer_min_index_reduce_longlong;
+    cilk_c_reducer_min_index_reduce_schar;
+    cilk_c_reducer_min_index_reduce_short;
+    cilk_c_reducer_min_index_reduce_uchar;
+    cilk_c_reducer_min_index_reduce_uint;
+    cilk_c_reducer_min_index_reduce_ulong;
+    cilk_c_reducer_min_index_reduce_ulonglong;
+    cilk_c_reducer_min_index_reduce_unsigned;
+    cilk_c_reducer_min_index_reduce_ushort;
+    cilk_c_reducer_min_index_reduce_wchar_t;
+    cilk_c_reducer_min_reduce_char;
+    cilk_c_reducer_min_reduce_double;
+    cilk_c_reducer_min_reduce_float;
+    cilk_c_reducer_min_reduce_int;
+    cilk_c_reducer_min_reduce_long;
+    cilk_c_reducer_min_reduce_longdouble;
+    cilk_c_reducer_min_reduce_longlong;
+    cilk_c_reducer_min_reduce_schar;
+    cilk_c_reducer_min_reduce_short;
+    cilk_c_reducer_min_reduce_uchar;
+    cilk_c_reducer_min_reduce_uint;
+    cilk_c_reducer_min_reduce_ulong;
+    cilk_c_reducer_min_reduce_ulonglong;
+    cilk_c_reducer_min_reduce_unsigned;
+    cilk_c_reducer_min_reduce_ushort;
+    cilk_c_reducer_min_reduce_wchar_t;
+    cilk_c_reducer_opadd_identity_char;
+    cilk_c_reducer_opadd_identity_double;
+    cilk_c_reducer_opadd_identity_float;
+    cilk_c_reducer_opadd_identity_int;
+    cilk_c_reducer_opadd_identity_long;
+    cilk_c_reducer_opadd_identity_longdouble;
+    cilk_c_reducer_opadd_identity_longlong;
+    cilk_c_reducer_opadd_identity_schar;
+    cilk_c_reducer_opadd_identity_short;
+    cilk_c_reducer_opadd_identity_uchar;
+    cilk_c_reducer_opadd_identity_uint;
+    cilk_c_reducer_opadd_identity_ulong;
+    cilk_c_reducer_opadd_identity_ulonglong;
+    cilk_c_reducer_opadd_identity_unsigned;
+    cilk_c_reducer_opadd_identity_ushort;
+    cilk_c_reducer_opadd_identity_wchar_t;
+    cilk_c_reducer_opadd_reduce_char;
+    cilk_c_reducer_opadd_reduce_double;
+    cilk_c_reducer_opadd_reduce_float;
+    cilk_c_reducer_opadd_reduce_int;
+    cilk_c_reducer_opadd_reduce_long;
+    cilk_c_reducer_opadd_reduce_longdouble;
+    cilk_c_reducer_opadd_reduce_longlong;
+    cilk_c_reducer_opadd_reduce_schar;
+    cilk_c_reducer_opadd_reduce_short;
+    cilk_c_reducer_opadd_reduce_uchar;
+    cilk_c_reducer_opadd_reduce_uint;
+    cilk_c_reducer_opadd_reduce_ulong;
+    cilk_c_reducer_opadd_reduce_ulonglong;
+    cilk_c_reducer_opadd_reduce_unsigned;
+    cilk_c_reducer_opadd_reduce_ushort;
+    cilk_c_reducer_opadd_reduce_wchar_t;
+    cilk_c_reducer_opand_identity_char;
+    cilk_c_reducer_opand_identity_int;
+    cilk_c_reducer_opand_identity_long;
+    cilk_c_reducer_opand_identity_longlong;
+    cilk_c_reducer_opand_identity_schar;
+    cilk_c_reducer_opand_identity_short;
+    cilk_c_reducer_opand_identity_uchar;
+    cilk_c_reducer_opand_identity_uint;
+    cilk_c_reducer_opand_identity_ulong;
+    cilk_c_reducer_opand_identity_ulonglong;
+    cilk_c_reducer_opand_identity_unsigned;
+    cilk_c_reducer_opand_identity_ushort;
+    cilk_c_reducer_opand_identity_wchar_t;
+    cilk_c_reducer_opand_reduce_char;
+    cilk_c_reducer_opand_reduce_int;
+    cilk_c_reducer_opand_reduce_long;
+    cilk_c_reducer_opand_reduce_longlong;
+    cilk_c_reducer_opand_reduce_schar;
+    cilk_c_reducer_opand_reduce_short;
+    cilk_c_reducer_opand_reduce_uchar;
+    cilk_c_reducer_opand_reduce_uint;
+    cilk_c_reducer_opand_reduce_ulong;
+    cilk_c_reducer_opand_reduce_ulonglong;
+    cilk_c_reducer_opand_reduce_unsigned;
+    cilk_c_reducer_opand_reduce_ushort;
+    cilk_c_reducer_opand_reduce_wchar_t;
+    cilk_c_reducer_opmul_identity_char;
+    cilk_c_reducer_opmul_identity_double;
+    cilk_c_reducer_opmul_identity_float;
+    cilk_c_reducer_opmul_identity_int;
+    cilk_c_reducer_opmul_identity_long;
+    cilk_c_reducer_opmul_identity_longdouble;
+    cilk_c_reducer_opmul_identity_longlong;
+    cilk_c_reducer_opmul_identity_schar;
+    cilk_c_reducer_opmul_identity_short;
+    cilk_c_reducer_opmul_identity_uchar;
+    cilk_c_reducer_opmul_identity_uint;
+    cilk_c_reducer_opmul_identity_ulong;
+    cilk_c_reducer_opmul_identity_ulonglong;
+    cilk_c_reducer_opmul_identity_unsigned;
+    cilk_c_reducer_opmul_identity_ushort;
+    cilk_c_reducer_opmul_identity_wchar_t;
+    cilk_c_reducer_opmul_reduce_char;
+    cilk_c_reducer_opmul_reduce_double;
+    cilk_c_reducer_opmul_reduce_float;
+    cilk_c_reducer_opmul_reduce_int;
+    cilk_c_reducer_opmul_reduce_long;
+    cilk_c_reducer_opmul_reduce_longdouble;
+    cilk_c_reducer_opmul_reduce_longlong;
+    cilk_c_reducer_opmul_reduce_schar;
+    cilk_c_reducer_opmul_reduce_short;
+    cilk_c_reducer_opmul_reduce_uchar;
+    cilk_c_reducer_opmul_reduce_uint;
+    cilk_c_reducer_opmul_reduce_ulong;
+    cilk_c_reducer_opmul_reduce_ulonglong;
+    cilk_c_reducer_opmul_reduce_unsigned;
+    cilk_c_reducer_opmul_reduce_ushort;
+    cilk_c_reducer_opmul_reduce_wchar_t;
+    cilk_c_reducer_opor_identity_char;
+    cilk_c_reducer_opor_identity_int;
+    cilk_c_reducer_opor_identity_long;
+    cilk_c_reducer_opor_identity_longlong;
+    cilk_c_reducer_opor_identity_schar;
+    cilk_c_reducer_opor_identity_short;
+    cilk_c_reducer_opor_identity_uchar;
+    cilk_c_reducer_opor_identity_uint;
+    cilk_c_reducer_opor_identity_ulong;
+    cilk_c_reducer_opor_identity_ulonglong;
+    cilk_c_reducer_opor_identity_unsigned;
+    cilk_c_reducer_opor_identity_ushort;
+    cilk_c_reducer_opor_identity_wchar_t;
+    cilk_c_reducer_opor_reduce_char;
+    cilk_c_reducer_opor_reduce_int;
+    cilk_c_reducer_opor_reduce_long;
+    cilk_c_reducer_opor_reduce_longlong;
+    cilk_c_reducer_opor_reduce_schar;
+    cilk_c_reducer_opor_reduce_short;
+    cilk_c_reducer_opor_reduce_uchar;
+    cilk_c_reducer_opor_reduce_uint;
+    cilk_c_reducer_opor_reduce_ulong;
+    cilk_c_reducer_opor_reduce_ulonglong;
+    cilk_c_reducer_opor_reduce_unsigned;
+    cilk_c_reducer_opor_reduce_ushort;
+    cilk_c_reducer_opor_reduce_wchar_t;
+    cilk_c_reducer_opxor_identity_char;
+    cilk_c_reducer_opxor_identity_int;
+    cilk_c_reducer_opxor_identity_long;
+    cilk_c_reducer_opxor_identity_longlong;
+    cilk_c_reducer_opxor_identity_schar;
+    cilk_c_reducer_opxor_identity_short;
+    cilk_c_reducer_opxor_identity_uchar;
+    cilk_c_reducer_opxor_identity_uint;
+    cilk_c_reducer_opxor_identity_ulong;
+    cilk_c_reducer_opxor_identity_ulonglong;
+    cilk_c_reducer_opxor_identity_unsigned;
+    cilk_c_reducer_opxor_identity_ushort;
+    cilk_c_reducer_opxor_identity_wchar_t;
+    cilk_c_reducer_opxor_reduce_char;
+    cilk_c_reducer_opxor_reduce_int;
+    cilk_c_reducer_opxor_reduce_long;
+    cilk_c_reducer_opxor_reduce_longlong;
+    cilk_c_reducer_opxor_reduce_schar;
+    cilk_c_reducer_opxor_reduce_short;
+    cilk_c_reducer_opxor_reduce_uchar;
+    cilk_c_reducer_opxor_reduce_uint;
+    cilk_c_reducer_opxor_reduce_ulong;
+    cilk_c_reducer_opxor_reduce_ulonglong;
+    cilk_c_reducer_opxor_reduce_unsigned;
+    cilk_c_reducer_opxor_reduce_ushort;
+    cilk_c_reducer_opxor_reduce_wchar_t;
+};
diff --git a/libcilkrts/runtime/local_state.c b/libcilkrts/runtime/local_state.c
new file mode 100644 (file)
index 0000000..14ac827
--- /dev/null
@@ -0,0 +1,68 @@
+/* local_state.c                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2010-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+#include "local_state.h"
+#include "bug.h"
+#include "full_frame.h"
+
+void run_scheduling_stack_fcn(__cilkrts_worker *w)
+{
+    scheduling_stack_fcn_t fcn = w->l->post_suspend;
+    full_frame *ff2 = w->l->frame_ff;
+    __cilkrts_stack_frame *sf2 = w->l->suspended_stack;
+
+    w->l->post_suspend = 0;
+    w->l->suspended_stack = 0;
+
+    // Conceptually, after clearing w->l->frame_ff,
+    // w no longer owns the full frame ff.
+    // The next time another (possibly different) worker takes
+    // ownership of ff will be at a provably_good_steal on ff. 
+    w->l->frame_ff = NULL;
+
+    CILK_ASSERT(fcn);
+    CILK_ASSERT(ff2);
+    fcn(w, ff2, sf2);
+
+    // After we run the scheduling stack function, we shouldn't
+    // (still) not have a full frame.
+    CILK_ASSERT(NULL == w->l->frame_ff);
+}
+
+/* End local_state.c */
diff --git a/libcilkrts/runtime/local_state.h b/libcilkrts/runtime/local_state.h
new file mode 100644 (file)
index 0000000..03f3989
--- /dev/null
@@ -0,0 +1,424 @@
+/* local_state.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file local_state.h
+ *
+ * @brief The local_state structure contains additional OS-independent
+ * information that's associated with a worker, but doesn't need to be visible
+ * to the code generated by the compiler.
+ */
+
+#ifndef INCLUDED_LOCAL_STATE_DOT_H
+#define INCLUDED_LOCAL_STATE_DOT_H
+
+#include <internal/abi.h>
+#include "worker_mutex.h"
+#include "global_state.h"
+#include "record-replay.h"
+#include "signal_node.h"
+
+#include <setjmp.h>
+#include <stddef.h>
+#include <stdio.h>
+
+
+#ifndef _WIN32
+#   include <pthread.h>
+#endif
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/* Opaque types. */
+
+struct full_frame;
+struct free_list;
+struct pending_exception_info;
+/// Opaque type for replay entry. 
+typedef struct replay_entry_t replay_entry_t;
+
+/**
+ * @brief Magic numbers for local_state, used for debugging
+ */
+typedef unsigned long long ls_magic_t;
+
+/**
+ * @brief Scheduling stack function: A function that is decided on the program stack,
+ * but that must be executed on the scheduling stack.
+ */
+typedef void (*scheduling_stack_fcn_t) (__cilkrts_worker *w,
+                                        struct full_frame *ff,
+                                        __cilkrts_stack_frame *sf);
+
+/**
+ * @brief Type of this worker.
+ **/
+typedef enum cilk_worker_type
+{
+    WORKER_FREE,    ///< Unused worker - available to be bound to user threads
+    WORKER_SYSTEM,  ///< Worker created by runtime - able to steal from any worker
+    WORKER_USER     ///< User thread - able to steal only from team members
+} cilk_worker_type;
+
+
+/**
+ * @brief The local_state structure contains additional OS-independent
+ * information that's associated with a worker, but doesn't need to be
+ * visible to the compiler.
+ *
+ * No compiler-generated code should need to know the layout of this
+ * structure.
+ *
+ * The fields of this struct can be classified as either local or
+ * shared.
+ *
+ *  Local: This field is only accessed by the thread bound to this
+ *    worker struct.  Local fields can be freely accessed without
+ *    acquiring locks.
+ *  
+ *  Shared: This field may be accessed by multiple worker threads.
+ *    Accesses to shared fields usually requires locks, except in
+ *    special situations where one can prove that locks are
+ *    unnecessary.
+ *
+ * The fields of this can also be classified as "read-only" if the
+ * field does not change after it is initialized.  Otherwise, the
+ * field is "read/write".  Read-only fields do not require locks to
+ * access (ignoring the synchronization that might be needed for
+ * initialization if this can occur in parallel).
+ *
+ * Finally, we explicitly classify some fields as "synchronization"
+ * fields if they are used as part of a synchronization protocol in
+ * the runtime.  These variables are generally shared and read/write.
+ * Mostly, this category includes lock variables and other variables
+ * that are involved in synchronization protocols (i.e., the THE
+ * protocol).
+ */
+struct local_state  /* COMMON_PORTABLE */
+{
+    /** This value should be in the first field in any local_state */
+#   define WORKER_MAGIC_0 ((ls_magic_t)0xe0831a4a940c60b8ULL)
+
+    /**
+     * Should be WORKER_MAGIC_0 or the local_state has been corrupted
+     * This magic field is shared because it is read on lock acquisitions.
+     *
+     * [shared read-only]
+     */
+    ls_magic_t worker_magic_0;
+
+    /**
+     * Mutex used to serialize access to the local_state
+     * Synchronization field. [shared read/write]
+     */
+    struct mutex lock;
+
+    /**
+     * Flag that indicates that the worker is interested in grabbing
+     * LOCK, and thus thieves should leave the worker alone.
+     * Written only by self, may be read by others.
+     *
+     * Synchronization field.  [shared read/write]
+     */
+    int do_not_steal;
+
+    /**
+     * Lock that all thieves grab in order to compete for the right
+     * to disturb this worker.
+     *
+     * Synchronization field. [shared read/write]
+     */
+    struct mutex steal_lock;
+
+    /**
+     * Full frame that the worker is working on.
+     *
+     * While a worker w is executing, a thief may change
+     * w->l->frame_ff (on a successful steal) after acquiring w's
+     * lock.
+     *
+     * Unlocked accesses to w->l->frame_ff are safe (by w itself) when
+     * w's deque is empty, or when stealing from w has been disabled.
+     *
+     * [shared read/write]
+     */
+    struct full_frame *frame_ff;
+
+    /**
+     * Full frame that the worker will be working on next
+     *
+     * This field is normally local for a worker w.  Another worker v
+     * may modify w->l->next_frame_ff, however, in the special case
+     * when v is returning a frame to a user thread w since w is the
+     * team leader.
+     *
+     * [shared read/write]
+     */
+    struct full_frame *next_frame_ff;
+
+    /**
+     * This is set iff this is a WORKER_USER and there has been a steal.  It
+     * points to the first frame that was stolen since the team was last fully
+     * sync'd.  Only this worker may continue past a sync in this function.
+     *
+     * This field is set by a thief for a victim that is a user
+     * thread, while holding the victim's lock.
+     * It can be cleared without a lock by the worker that will
+     * continue exuecting past the sync.
+     *
+     * [shared read/write]
+     */
+    struct full_frame *last_full_frame;
+
+    /**
+     * Team on which this worker is a participant.  When a user worker enters,
+     * its team is its own worker struct and it can never change teams.  When a
+     * system worker steals, it adopts the team of its victim.
+     *
+     * When a system worker w steals, it reads victim->l->team and
+     * joins this team.  w->l->team is constant until the next time w
+     * returns control to the runtime.
+     * We must acquire the worker lock to change w->l->team.
+     *
+     * @note This field is 64-byte aligned because it is the first in
+     * the group of shared read-only fields.  We want this group to
+     * fall on a different cache line from the previous group, which
+     * is shared read-write.
+     *
+     * [shared read-only]
+     */
+    __attribute__((aligned(64)))
+    __cilkrts_worker *team;
+
+    /**
+     * Type of this worker
+     *
+     * This field changes only when a worker binds or unbinds.
+     * Otherwise, the field is read-only while the worker is bound.
+     *
+     * [shared read-only]
+     */
+    cilk_worker_type type;
+    
+    /**
+     * Lazy task queue of this worker - an array of pointers to stack frames.
+     *
+     * Read-only because deques are a fixed size in the current
+     * implementation.
+     *
+     * @note This field is 64-byte aligned because it is the first in
+     * the group of local fields.  We want this group to fall on a
+     * different cache line from the previous group, which is shared
+     * read-only.
+     *
+     * [local read-only]
+     */
+    __attribute__((aligned(64)))
+    __cilkrts_stack_frame **ltq;
+
+    /**
+     * Pool of fibers waiting to be reused.
+     * [local read/write]
+     */
+    cilk_fiber_pool fiber_pool;
+
+    /**
+     * The fiber for the scheduling stacks.
+     * [local read/write]
+     */
+    cilk_fiber* scheduling_fiber;
+
+    /**
+     * Saved pointer to the leaf node in thread-local storage, when a
+     * user thread is imported.  This pointer gets set to a
+     * meaningful value when binding a user thread, and cleared on
+     * unbind.
+     *
+     * [local read/write]
+     */
+    __cilkrts_pedigree* original_pedigree_leaf;
+
+    /**
+     * State of the random number generator
+     * 
+     * [local read/write]
+     */
+    unsigned rand_seed;
+
+    /**
+     * Function to execute after transferring onto the scheduling stack.
+     *
+     * [local read/write]
+     */
+    scheduling_stack_fcn_t post_suspend;
+
+    /**
+     * __cilkrts_stack_frame we suspended when we transferred onto the
+     * scheduling stack.    
+     *
+     * [local read/write]
+     */
+    __cilkrts_stack_frame *suspended_stack;
+
+    /**
+     * cilk_fiber that should be freed after returning from a
+     *  spawn with a stolen parent or after stalling at a sync.
+
+     *  We calculate the stack to free when executing a reduction on
+     *  the user stack, but we can not actually release the stack
+     *  until control longjmps onto a runtime scheduling stack.
+     *
+     * This field is used to pass information to the runtime across
+     * the longjmp onto the scheduling stack.
+     *
+     * [local read/write]
+     */
+    cilk_fiber* fiber_to_free;
+
+    /**
+     * Saved exception object for an exception that is being passed to
+     * our parent
+     *
+     * [local read/write]
+     */
+    struct pending_exception_info *pending_exception;
+
+    /**
+     * Buckets for the memory allocator
+     *
+     * [local read/write]
+     */
+    struct free_list *free_list[FRAME_MALLOC_NBUCKETS];
+
+    /**
+     * Potential function for the memory allocator
+     *
+     * [local read/write]
+     */
+    size_t bucket_potential[FRAME_MALLOC_NBUCKETS];
+
+    /**
+     * Support for statistics
+     *
+     * Useful only when CILK_PROFIlE is compiled in. 
+     * [local read/write]
+     */
+    statistics* stats;
+
+    /**
+     * Count indicates number of failures since last successful steal.  This is
+     * used by the scheduler to reduce contention on shared flags.
+     *
+     * [local read/write]
+     */
+    unsigned int steal_failure_count;
+
+    /**
+     * 1 if work was stolen from another worker.  When true, this will flag
+     * setup_for_execution_pedigree to increment the pedigree when we resume
+     * execution to match the increment that would have been done on a return
+     * from a spawn helper.
+     *
+     * [local read/write]
+     */
+    int work_stolen;
+
+    /**
+     * File pointer for record or replay
+     * Does FILE * work on Windows?
+     * During record, the file will be opened in write-only mode.
+     * During replay, the file will be opened in read-only mode.
+     *
+     * [local read/write]
+     */
+    FILE *record_replay_fptr;
+
+    /**
+     * Root of array of replay entries - NULL if we're not replaying a log
+     *
+     * [local read/write]
+     */
+    replay_entry_t *replay_list_root;
+
+    /**
+     * Current replay entry - NULL if we're not replaying a log
+     *
+     * [local read/write]
+     */
+    replay_entry_t *replay_list_entry;
+    
+    /**
+     * Separate the signal_node from other things in the local_state by the
+     * sizeof a cache line for performance reasons.
+     *
+     * unused 
+     */
+    char buf[64];
+
+    /**
+     * Signal object for waking/sleeping the worker.  This should be a pointer
+     * to avoid the possibility of caching problems.
+     *
+     * [shared read-only]
+     */
+     signal_node_t *signal_node;
+
+    /** This value should be in the last field in any local_state */
+#   define WORKER_MAGIC_1 ((ls_magic_t)0x16164afb0ea0dff9ULL)
+
+    /**
+     * Should be WORKER_MAGIC_1 or the local_state has been corrupted
+     * This magic field is shared because it is read on lock acquisitions.
+     * [shared read-only]
+     */
+    ls_magic_t worker_magic_1;
+};
+
+/**
+ * Perform cleanup according to the function set before the longjmp().
+ *
+ * Call this after longjmp() has completed and the worker is back on a
+ * scheduling stack.
+ *
+ * @param w __cilkrts_worker currently executing.
+ */
+void run_scheduling_stack_fcn(__cilkrts_worker *w);
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_LOCAL_STATE_DOT_H)
diff --git a/libcilkrts/runtime/mac-symbols.txt b/libcilkrts/runtime/mac-symbols.txt
new file mode 100644 (file)
index 0000000..38d83a8
--- /dev/null
@@ -0,0 +1,318 @@
+# Exported symbol list:
+___cilkrts_bind_thread
+___cilkrts_bind_thread_1
+___cilkrts_bump_loop_rank
+___cilkrts_bump_loop_rank_internal
+___cilkrts_bump_worker_rank
+___cilkrts_bump_worker_rank_internal
+___cilkrts_cilk_for_32
+___cilkrts_cilk_for_64
+___cilkrts_debugger_notification
+___cilkrts_dump_stats
+___cilkrts_end_cilk
+___cilkrts_enter_frame
+___cilkrts_enter_frame_1
+___cilkrts_enter_frame_fast
+___cilkrts_enter_frame_fast_1
+___cilkrts_get_force_reduce
+___cilkrts_get_nworkers
+___cilkrts_get_pedigree_info
+___cilkrts_get_pedigree_internal
+___cilkrts_get_sf
+___cilkrts_get_stack_size
+___cilkrts_get_tls_worker
+___cilkrts_get_tls_worker_fast
+___cilkrts_get_total_workers
+___cilkrts_get_worker_number
+___cilkrts_get_worker_rank
+___cilkrts_global_state
+___cilkrts_hyper_create
+___cilkrts_hyper_destroy
+___cilkrts_hyper_lookup
+___cilkrts_hyperobject_alloc
+___cilkrts_hyperobject_dealloc
+___cilkrts_hyperobject_noop_destroy
+___cilkrts_init
+___cilkrts_irml_version
+___cilkrts_leave_frame
+___cilkrts_metacall
+___cilkrts_rethrow
+___cilkrts_return_exception
+___cilkrts_save_fp_ctrl_state
+___cilkrts_set_param
+___cilkrts_stack_alloc
+___cilkrts_stack_free
+___cilkrts_sync
+___cilkrts_synched
+___cilkrts_watch_stack
+___cilkrts_worker_stub
+_cilk_c_reducer_max_identity_char
+_cilk_c_reducer_max_identity_double
+_cilk_c_reducer_max_identity_float
+_cilk_c_reducer_max_identity_int
+_cilk_c_reducer_max_identity_long
+_cilk_c_reducer_max_identity_longdouble
+_cilk_c_reducer_max_identity_longlong
+_cilk_c_reducer_max_identity_schar
+_cilk_c_reducer_max_identity_short
+_cilk_c_reducer_max_identity_uchar
+_cilk_c_reducer_max_identity_uint
+_cilk_c_reducer_max_identity_ulong
+_cilk_c_reducer_max_identity_ulonglong
+_cilk_c_reducer_max_identity_unsigned
+_cilk_c_reducer_max_identity_ushort
+_cilk_c_reducer_max_identity_wchar_t
+_cilk_c_reducer_max_index_identity_char
+_cilk_c_reducer_max_index_identity_double
+_cilk_c_reducer_max_index_identity_float
+_cilk_c_reducer_max_index_identity_int
+_cilk_c_reducer_max_index_identity_long
+_cilk_c_reducer_max_index_identity_longdouble
+_cilk_c_reducer_max_index_identity_longlong
+_cilk_c_reducer_max_index_identity_schar
+_cilk_c_reducer_max_index_identity_short
+_cilk_c_reducer_max_index_identity_uchar
+_cilk_c_reducer_max_index_identity_uint
+_cilk_c_reducer_max_index_identity_ulong
+_cilk_c_reducer_max_index_identity_ulonglong
+_cilk_c_reducer_max_index_identity_unsigned
+_cilk_c_reducer_max_index_identity_ushort
+_cilk_c_reducer_max_index_identity_wchar_t
+_cilk_c_reducer_max_index_reduce_char
+_cilk_c_reducer_max_index_reduce_double
+_cilk_c_reducer_max_index_reduce_float
+_cilk_c_reducer_max_index_reduce_int
+_cilk_c_reducer_max_index_reduce_long
+_cilk_c_reducer_max_index_reduce_longdouble
+_cilk_c_reducer_max_index_reduce_longlong
+_cilk_c_reducer_max_index_reduce_schar
+_cilk_c_reducer_max_index_reduce_short
+_cilk_c_reducer_max_index_reduce_uchar
+_cilk_c_reducer_max_index_reduce_uint
+_cilk_c_reducer_max_index_reduce_ulong
+_cilk_c_reducer_max_index_reduce_ulonglong
+_cilk_c_reducer_max_index_reduce_unsigned
+_cilk_c_reducer_max_index_reduce_ushort
+_cilk_c_reducer_max_index_reduce_wchar_t
+_cilk_c_reducer_max_reduce_char
+_cilk_c_reducer_max_reduce_double
+_cilk_c_reducer_max_reduce_float
+_cilk_c_reducer_max_reduce_int
+_cilk_c_reducer_max_reduce_long
+_cilk_c_reducer_max_reduce_longdouble
+_cilk_c_reducer_max_reduce_longlong
+_cilk_c_reducer_max_reduce_schar
+_cilk_c_reducer_max_reduce_short
+_cilk_c_reducer_max_reduce_uchar
+_cilk_c_reducer_max_reduce_uint
+_cilk_c_reducer_max_reduce_ulong
+_cilk_c_reducer_max_reduce_ulonglong
+_cilk_c_reducer_max_reduce_unsigned
+_cilk_c_reducer_max_reduce_ushort
+_cilk_c_reducer_max_reduce_wchar_t
+_cilk_c_reducer_min_identity_char
+_cilk_c_reducer_min_identity_double
+_cilk_c_reducer_min_identity_float
+_cilk_c_reducer_min_identity_int
+_cilk_c_reducer_min_identity_long
+_cilk_c_reducer_min_identity_longdouble
+_cilk_c_reducer_min_identity_longlong
+_cilk_c_reducer_min_identity_schar
+_cilk_c_reducer_min_identity_short
+_cilk_c_reducer_min_identity_uchar
+_cilk_c_reducer_min_identity_uint
+_cilk_c_reducer_min_identity_ulong
+_cilk_c_reducer_min_identity_ulonglong
+_cilk_c_reducer_min_identity_unsigned
+_cilk_c_reducer_min_identity_ushort
+_cilk_c_reducer_min_identity_wchar_t
+_cilk_c_reducer_min_index_identity_char
+_cilk_c_reducer_min_index_identity_double
+_cilk_c_reducer_min_index_identity_float
+_cilk_c_reducer_min_index_identity_int
+_cilk_c_reducer_min_index_identity_long
+_cilk_c_reducer_min_index_identity_longdouble
+_cilk_c_reducer_min_index_identity_longlong
+_cilk_c_reducer_min_index_identity_schar
+_cilk_c_reducer_min_index_identity_short
+_cilk_c_reducer_min_index_identity_uchar
+_cilk_c_reducer_min_index_identity_uint
+_cilk_c_reducer_min_index_identity_ulong
+_cilk_c_reducer_min_index_identity_ulonglong
+_cilk_c_reducer_min_index_identity_unsigned
+_cilk_c_reducer_min_index_identity_ushort
+_cilk_c_reducer_min_index_identity_wchar_t
+_cilk_c_reducer_min_index_reduce_char
+_cilk_c_reducer_min_index_reduce_double
+_cilk_c_reducer_min_index_reduce_float
+_cilk_c_reducer_min_index_reduce_int
+_cilk_c_reducer_min_index_reduce_long
+_cilk_c_reducer_min_index_reduce_longdouble
+_cilk_c_reducer_min_index_reduce_longlong
+_cilk_c_reducer_min_index_reduce_schar
+_cilk_c_reducer_min_index_reduce_short
+_cilk_c_reducer_min_index_reduce_uchar
+_cilk_c_reducer_min_index_reduce_uint
+_cilk_c_reducer_min_index_reduce_ulong
+_cilk_c_reducer_min_index_reduce_ulonglong
+_cilk_c_reducer_min_index_reduce_unsigned
+_cilk_c_reducer_min_index_reduce_ushort
+_cilk_c_reducer_min_index_reduce_wchar_t
+_cilk_c_reducer_min_reduce_char
+_cilk_c_reducer_min_reduce_double
+_cilk_c_reducer_min_reduce_float
+_cilk_c_reducer_min_reduce_int
+_cilk_c_reducer_min_reduce_long
+_cilk_c_reducer_min_reduce_longdouble
+_cilk_c_reducer_min_reduce_longlong
+_cilk_c_reducer_min_reduce_schar
+_cilk_c_reducer_min_reduce_short
+_cilk_c_reducer_min_reduce_uchar
+_cilk_c_reducer_min_reduce_uint
+_cilk_c_reducer_min_reduce_ulong
+_cilk_c_reducer_min_reduce_ulonglong
+_cilk_c_reducer_min_reduce_unsigned
+_cilk_c_reducer_min_reduce_ushort
+_cilk_c_reducer_min_reduce_wchar_t
+_cilk_c_reducer_opadd_identity_char
+_cilk_c_reducer_opadd_identity_double
+_cilk_c_reducer_opadd_identity_float
+_cilk_c_reducer_opadd_identity_int
+_cilk_c_reducer_opadd_identity_long
+_cilk_c_reducer_opadd_identity_longdouble
+_cilk_c_reducer_opadd_identity_longlong
+_cilk_c_reducer_opadd_identity_schar
+_cilk_c_reducer_opadd_identity_short
+_cilk_c_reducer_opadd_identity_uchar
+_cilk_c_reducer_opadd_identity_uint
+_cilk_c_reducer_opadd_identity_ulong
+_cilk_c_reducer_opadd_identity_ulonglong
+_cilk_c_reducer_opadd_identity_unsigned
+_cilk_c_reducer_opadd_identity_ushort
+_cilk_c_reducer_opadd_identity_wchar_t
+_cilk_c_reducer_opadd_reduce_char
+_cilk_c_reducer_opadd_reduce_double
+_cilk_c_reducer_opadd_reduce_float
+_cilk_c_reducer_opadd_reduce_int
+_cilk_c_reducer_opadd_reduce_long
+_cilk_c_reducer_opadd_reduce_longdouble
+_cilk_c_reducer_opadd_reduce_longlong
+_cilk_c_reducer_opadd_reduce_schar
+_cilk_c_reducer_opadd_reduce_short
+_cilk_c_reducer_opadd_reduce_uchar
+_cilk_c_reducer_opadd_reduce_uint
+_cilk_c_reducer_opadd_reduce_ulong
+_cilk_c_reducer_opadd_reduce_ulonglong
+_cilk_c_reducer_opadd_reduce_unsigned
+_cilk_c_reducer_opadd_reduce_ushort
+_cilk_c_reducer_opadd_reduce_wchar_t
+_cilk_c_reducer_opand_identity_char
+_cilk_c_reducer_opand_identity_int
+_cilk_c_reducer_opand_identity_long
+_cilk_c_reducer_opand_identity_longlong
+_cilk_c_reducer_opand_identity_schar
+_cilk_c_reducer_opand_identity_short
+_cilk_c_reducer_opand_identity_uchar
+_cilk_c_reducer_opand_identity_uint
+_cilk_c_reducer_opand_identity_ulong
+_cilk_c_reducer_opand_identity_ulonglong
+_cilk_c_reducer_opand_identity_unsigned
+_cilk_c_reducer_opand_identity_ushort
+_cilk_c_reducer_opand_identity_wchar_t
+_cilk_c_reducer_opand_reduce_char
+_cilk_c_reducer_opand_reduce_int
+_cilk_c_reducer_opand_reduce_long
+_cilk_c_reducer_opand_reduce_longlong
+_cilk_c_reducer_opand_reduce_schar
+_cilk_c_reducer_opand_reduce_short
+_cilk_c_reducer_opand_reduce_uchar
+_cilk_c_reducer_opand_reduce_uint
+_cilk_c_reducer_opand_reduce_ulong
+_cilk_c_reducer_opand_reduce_ulonglong
+_cilk_c_reducer_opand_reduce_unsigned
+_cilk_c_reducer_opand_reduce_ushort
+_cilk_c_reducer_opand_reduce_wchar_t
+_cilk_c_reducer_opmul_identity_char
+_cilk_c_reducer_opmul_identity_double
+_cilk_c_reducer_opmul_identity_float
+_cilk_c_reducer_opmul_identity_int
+_cilk_c_reducer_opmul_identity_long
+_cilk_c_reducer_opmul_identity_longdouble
+_cilk_c_reducer_opmul_identity_longlong
+_cilk_c_reducer_opmul_identity_schar
+_cilk_c_reducer_opmul_identity_short
+_cilk_c_reducer_opmul_identity_uchar
+_cilk_c_reducer_opmul_identity_uint
+_cilk_c_reducer_opmul_identity_ulong
+_cilk_c_reducer_opmul_identity_ulonglong
+_cilk_c_reducer_opmul_identity_unsigned
+_cilk_c_reducer_opmul_identity_ushort
+_cilk_c_reducer_opmul_identity_wchar_t
+_cilk_c_reducer_opmul_reduce_char
+_cilk_c_reducer_opmul_reduce_double
+_cilk_c_reducer_opmul_reduce_float
+_cilk_c_reducer_opmul_reduce_int
+_cilk_c_reducer_opmul_reduce_long
+_cilk_c_reducer_opmul_reduce_longdouble
+_cilk_c_reducer_opmul_reduce_longlong
+_cilk_c_reducer_opmul_reduce_schar
+_cilk_c_reducer_opmul_reduce_short
+_cilk_c_reducer_opmul_reduce_uchar
+_cilk_c_reducer_opmul_reduce_uint
+_cilk_c_reducer_opmul_reduce_ulong
+_cilk_c_reducer_opmul_reduce_ulonglong
+_cilk_c_reducer_opmul_reduce_unsigned
+_cilk_c_reducer_opmul_reduce_ushort
+_cilk_c_reducer_opmul_reduce_wchar_t
+_cilk_c_reducer_opor_identity_char
+_cilk_c_reducer_opor_identity_int
+_cilk_c_reducer_opor_identity_long
+_cilk_c_reducer_opor_identity_longlong
+_cilk_c_reducer_opor_identity_schar
+_cilk_c_reducer_opor_identity_short
+_cilk_c_reducer_opor_identity_uchar
+_cilk_c_reducer_opor_identity_uint
+_cilk_c_reducer_opor_identity_ulong
+_cilk_c_reducer_opor_identity_ulonglong
+_cilk_c_reducer_opor_identity_unsigned
+_cilk_c_reducer_opor_identity_ushort
+_cilk_c_reducer_opor_identity_wchar_t
+_cilk_c_reducer_opor_reduce_char
+_cilk_c_reducer_opor_reduce_int
+_cilk_c_reducer_opor_reduce_long
+_cilk_c_reducer_opor_reduce_longlong
+_cilk_c_reducer_opor_reduce_schar
+_cilk_c_reducer_opor_reduce_short
+_cilk_c_reducer_opor_reduce_uchar
+_cilk_c_reducer_opor_reduce_uint
+_cilk_c_reducer_opor_reduce_ulong
+_cilk_c_reducer_opor_reduce_ulonglong
+_cilk_c_reducer_opor_reduce_unsigned
+_cilk_c_reducer_opor_reduce_ushort
+_cilk_c_reducer_opor_reduce_wchar_t
+_cilk_c_reducer_opxor_identity_char
+_cilk_c_reducer_opxor_identity_int
+_cilk_c_reducer_opxor_identity_long
+_cilk_c_reducer_opxor_identity_longlong
+_cilk_c_reducer_opxor_identity_schar
+_cilk_c_reducer_opxor_identity_short
+_cilk_c_reducer_opxor_identity_uchar
+_cilk_c_reducer_opxor_identity_uint
+_cilk_c_reducer_opxor_identity_ulong
+_cilk_c_reducer_opxor_identity_ulonglong
+_cilk_c_reducer_opxor_identity_unsigned
+_cilk_c_reducer_opxor_identity_ushort
+_cilk_c_reducer_opxor_identity_wchar_t
+_cilk_c_reducer_opxor_reduce_char
+_cilk_c_reducer_opxor_reduce_int
+_cilk_c_reducer_opxor_reduce_long
+_cilk_c_reducer_opxor_reduce_longlong
+_cilk_c_reducer_opxor_reduce_schar
+_cilk_c_reducer_opxor_reduce_short
+_cilk_c_reducer_opxor_reduce_uchar
+_cilk_c_reducer_opxor_reduce_uint
+_cilk_c_reducer_opxor_reduce_ulong
+_cilk_c_reducer_opxor_reduce_ulonglong
+_cilk_c_reducer_opxor_reduce_unsigned
+_cilk_c_reducer_opxor_reduce_ushort
+_cilk_c_reducer_opxor_reduce_wchar_t
diff --git a/libcilkrts/runtime/metacall_impl.c b/libcilkrts/runtime/metacall_impl.c
new file mode 100644 (file)
index 0000000..ce1c51a
--- /dev/null
@@ -0,0 +1,167 @@
+/* metacall_impl.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#include "metacall_impl.h"
+
+NOINLINE
+CILK_API_VOID
+__cilkrts_metacall(unsigned int tool, unsigned int code, void *data)
+{
+#ifdef ENABLE_NOTIFY_ZC_INTRINSIC
+    // The metacall type, code and data are packed together into a single
+    // struct which will be interpreted by the tool. This function is the
+    // one and only use of a "cilkscreen_metacall" annotation
+    metacall_data_t d = { tool, code, data };
+
+    // Note that Inspector uses probe mode, and is implementing the metacall
+    // interface to force the runtime to run with a single worker.  So
+    // __cilkrts_metacall must use __notify_intrinsic instead of
+    // __notify_zc_intrinsic
+    __notify_intrinsic("cilkscreen_metacall", &d);
+#endif // ENABLE_NOTIFY_ZC_INTRINSIC
+}
+
+int __cilkrts_running_under_sequential_ptool(void)
+{
+    static int running_under_sequential_ptool = -1;
+    volatile char c = ~0;
+
+    // If we haven't been called before, see if we're running under Cilkscreen
+    // or Cilkview
+    if (-1 == running_under_sequential_ptool)
+    {
+        // metacall #2 writes 0 in C if we are running under
+        // a p-tools that requires serial execution, and is a 
+        // no-op otherwise
+        //
+        // Note that removing the volatile is required to prevent the compiler
+        // from assuming that the value has not changed
+        __cilkrts_metacall(METACALL_TOOL_SYSTEM,
+                           HYPER_ZERO_IF_SEQUENTIAL_PTOOL, (void *)&c);
+
+        running_under_sequential_ptool = (0 == c);
+    }
+
+    return running_under_sequential_ptool;
+}
+
+/*
+ * __cilkrts_cilkscreen_establish_c_stack
+ *
+ * Notify Cilkscreen of the extent of the stack
+ */
+
+void __cilkrts_cilkscreen_establish_c_stack(char *begin, char *end)
+{
+    char *limits[2] = {begin, end};
+
+    __cilkrts_metacall(METACALL_TOOL_SYSTEM, HYPER_ESTABLISH_C_STACK, limits);
+}
+
+#ifdef WORKSPAN // Workspan stuff - remove when we're sure what we can drop
+
+void __cilkview_workspan_start(void) {
+  __cilkrts_metacall(HYPER_WORKSPAN_START, 0);
+}
+
+void __cilkview_workspan_stop(void) {
+  __cilkrts_metacall(HYPER_WORKSPAN_STOP, 0);
+}
+
+void __cilkview_workspan_dump(const char *str) {
+  __cilkrts_metacall(HYPER_WORKSPAN_DUMP, (void*)str);
+}
+
+
+void __cilkview_workspan_reset(void) {
+  __cilkrts_metacall(HYPER_WORKSPAN_RESET, 0);
+}
+
+
+void __cilkview_use_default_grain(void) {
+    __cilkrts_metacall(HYPER_USE_DEFAULT_GRAIN, 0);
+}
+
+void __cilkview_get_workspan_data(unsigned long long *values, int size)
+{
+    void *data[2];
+
+    /* reset counters to zero in case we are not running under
+       a p-tool */
+
+    values[0] = 0;
+
+    data[0] = (void*) values;
+    data[1] = (void*) &size;
+     __cilkrts_metacall(HYPER_WORKSPAN_QUERY, &data);
+}
+
+void __cilkview_workspan_connected (int *flag) {
+  *flag = 0;
+  __cilkrts_metacall(HYPER_WORKSPAN_CONNECTED, (void *)flag);
+}
+
+void __cilkview_workspan_suspend() {
+  __cilkrts_metacall(HYPER_WORKSPAN_SUSPEND, 0);
+}
+
+void __cilkview_workspan_resume() {
+  __cilkrts_metacall(HYPER_WORKSPAN_RESUME, 0);
+}
+
+/* depreciated interfaces */
+void __cilkometer_workspan_start(void) {
+  __cilkrts_metacall(HYPER_WORKSPAN_START, 0);
+}
+
+void __cilkometer_workspan_stop(void) {
+  __cilkrts_metacall(HYPER_WORKSPAN_STOP, 0);
+}
+
+void __cilkometer_workspan_dump(const char *str) {
+  __cilkrts_metacall(HYPER_WORKSPAN_DUMP, (void*)str);
+}
+
+
+void __cilkometer_workspan_reset(void) {
+  __cilkrts_metacall(HYPER_WORKSPAN_RESET, 0);
+}
+
+#endif // WORKSPAN
+
+/* End metacall_impl.c */
diff --git a/libcilkrts/runtime/metacall_impl.h b/libcilkrts/runtime/metacall_impl.h
new file mode 100644 (file)
index 0000000..90cc7f9
--- /dev/null
@@ -0,0 +1,123 @@
+/* metacall_impl.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2010-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+/**
+ * @file metacall_impl.h
+ *
+ * @brief Meta-function calls to be used within the Cilk runtime system.
+ * 
+ * These differ from the macros in cilkscreen.h and cilkview.h because they go
+ * through the __cilkrts_metacall interface, which ensures that the operation
+ * is performed even when instrumentation is disabled.
+ */
+
+#ifndef INCLUDED_CILKRTS_METACALL_H
+#define INCLUDED_CILKRTS_METACALL_H
+
+#include "rts-common.h"
+#include <internal/metacall.h>
+#include <cilk/common.h>
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * This function is effectively an unconditional call from the runtime into
+ * a tool.  It is used for operations that must be performed by the tool,
+ * even when the tool is not instrumenting.  For example, Cilkscreen always
+ * recognizes the address of this function and performs the action specified
+ * in the contained metadata.
+ *
+ * Note that this function MUST NOT BE INLINED within the runtime.  This must
+ * be the ONLY instance of the cilkscreen_metacall metadata.
+ */
+CILK_API_VOID
+__cilkrts_metacall(unsigned int tool, unsigned int code, void *data);
+
+/**
+ * Return non-zero if running under Cilkscreen or Cilkview
+ */
+COMMON_PORTABLE
+int __cilkrts_running_under_sequential_ptool(void);
+
+/**
+ * Disable Cilkscreen implementation
+ */
+#define __cilkrts_cilkscreen_disable_instrumentation() \
+    __cilkrts_metacall(METACALL_TOOL_SYSTEM, HYPER_DISABLE_INSTRUMENTATION, 0)
+
+/**
+ * Enable Cilkscreen implementation
+ */
+#define __cilkrts_cilkscreen_enable_instrumentation() \
+    __cilkrts_metacall(METACALL_TOOL_SYSTEM, HYPER_ENABLE_INSTRUMENTATION, 0)
+
+/**
+ * Set the worker on entering runtime.
+ *
+ * @attention Deprecated in favor of __cilkrts_cilkscreen_ignore_block.  The
+ * begin/enter pairs in the current metadata mean Cilkscreen no longer has to
+ * have improper knowledge of the __cilkrts_worker or __cilkrts_stack_frame
+ * structures.
+ */
+#define __cilkrts_cilkscreen_establish_worker(w) \
+    __cilkrts_metacall(METACALL_TOOL_SYSTEM, HYPER_ESTABLISH_WORKER, w)
+
+/**
+ * Notify Cilkscreen of the extent of the stack.
+ *
+ * @param[in] begin Start (low address) of stack
+ * @param[in] end   One past high address of stack
+ */
+void __cilkrts_cilkscreen_establish_c_stack(char *begin, char *end);
+
+/**
+ * Tell tools to ignore a block of memory - currently the global state and
+ * memory allocated for workers.
+ */
+#define __cilkrts_cilkscreen_ignore_block(_begin, _end) \
+{                                                       \
+    void *block[2] = {_begin, _end};                    \
+    __cilkrts_metacall(METACALL_TOOL_SYSTEM,            \
+                       HYPER_IGNORE_MEMORY_BLOCK,       \
+                       block);                          \
+}
+
+__CILKRTS_END_EXTERN_C
+
+#endif /* ! defined(INCLUDED_CILKRTS_METACALL_H) */
diff --git a/libcilkrts/runtime/os-unix.c b/libcilkrts/runtime/os-unix.c
new file mode 100644 (file)
index 0000000..b48fd62
--- /dev/null
@@ -0,0 +1,508 @@
+/* os-unix.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#ifdef __linux__
+    // define _GNU_SOURCE before *any* #include.
+    // Even <stdint.h> will break later #includes if this macro is not
+    // already defined when it is #included.
+#   define _GNU_SOURCE
+#endif
+
+#include "os.h"
+#include "bug.h"
+#include "cilk_malloc.h"
+#include <internal/abi.h>
+
+#if defined __linux__
+#   include <sys/sysinfo.h>
+#   include <sys/syscall.h>
+#elif defined __APPLE__
+#   include <sys/sysctl.h>
+    // Uses sysconf(_SC_NPROCESSORS_ONLN) in verbose output
+#elif defined  __FreeBSD__
+// No additional include files
+#elif defined __CYGWIN__
+// Cygwin on Windows - no additional include files
+#elif defined  __VXWORKS__
+#   include <vxWorks.h>   
+#   include <vxCpuLib.h>   
+#   include <taskLib.h>   
+#else
+#   error "Unsupported OS"
+#endif
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/types.h>
+
+
+
+// /* Thread-local storage */
+// #ifdef _WIN32
+// typedef unsigned cilkos_tls_key_t;
+// #else
+// typedef pthread_key_t cilkos_tls_key_t;
+// #endif
+// cilkos_tls_key_t cilkos_allocate_tls_key();
+// void cilkos_set_tls_pointer(cilkos_tls_key_t key, void* ptr);
+// void* cilkos_get_tls_pointer(cilkos_tls_key_t key);
+
+#if !defined CILK_WORKER_TLS
+static int cilk_keys_defined;
+static pthread_key_t worker_key, pedigree_leaf_key, tbb_interop_key;
+
+#if SUPPORT_GET_CURRENT_FIBER > 0
+static pthread_key_t fiber_key;
+#endif
+
+static void *serial_worker;
+
+
+// This destructor is called when a pthread dies to deallocate the
+// pedigree node.
+static void __cilkrts_pedigree_leaf_destructor(void* pedigree_tls_ptr)
+{
+    __cilkrts_pedigree* pedigree_tls
+       = (__cilkrts_pedigree*)pedigree_tls_ptr;
+    if (pedigree_tls) {
+        // Assert that we have either one or two nodes
+        // left in the pedigree chain.
+        // If we have more, then something is going wrong...
+        CILK_ASSERT(!pedigree_tls->parent || !pedigree_tls->parent->parent);
+       __cilkrts_free(pedigree_tls);
+    }
+}
+
+void __cilkrts_init_tls_variables(void)
+{
+    int status;
+    /* This will be called once in serial execution before any
+       Cilk parallelism so we do not need to worry about races
+       on cilk_keys_defined. */
+    if (cilk_keys_defined)
+        return;
+    status = pthread_key_create(&worker_key, NULL);
+    CILK_ASSERT (status == 0);
+    status = pthread_key_create(&pedigree_leaf_key,
+                               __cilkrts_pedigree_leaf_destructor);
+    CILK_ASSERT (status == 0);
+    status = pthread_key_create(&tbb_interop_key, NULL);
+    CILK_ASSERT (status == 0);
+
+#if SUPPORT_GET_CURRENT_FIBER > 0    
+    status = pthread_key_create(&fiber_key, NULL);
+    CILK_ASSERT (status == 0);
+#endif
+    cilk_keys_defined = 1;
+    return;
+}
+
+COMMON_SYSDEP
+void* cilkos_get_current_thread_id(void)
+{
+    return (void*)pthread_self();
+}
+
+
+CILK_ABI_WORKER_PTR __cilkrts_get_tls_worker()
+{
+    if (__builtin_expect(cilk_keys_defined, 1))
+        return (__cilkrts_worker *)pthread_getspecific(worker_key);
+    else 
+        return serial_worker;
+    
+}
+
+CILK_ABI_WORKER_PTR __cilkrts_get_tls_worker_fast()
+{
+  return (__cilkrts_worker *)pthread_getspecific(worker_key);
+}
+
+COMMON_SYSDEP
+__cilk_tbb_stack_op_thunk *__cilkrts_get_tls_tbb_interop(void)
+{
+    if (__builtin_expect(cilk_keys_defined, 1))
+        return (__cilk_tbb_stack_op_thunk *)
+            pthread_getspecific(tbb_interop_key);
+    else
+        return 0;
+}
+
+// This counter should be updated atomically.
+static int __cilkrts_global_pedigree_tls_counter = -1;
+
+COMMON_SYSDEP
+__cilkrts_pedigree *__cilkrts_get_tls_pedigree_leaf(int create_new)
+{
+    __cilkrts_pedigree *pedigree_tls;    
+    if (__builtin_expect(cilk_keys_defined, 1)) {
+        pedigree_tls =
+            (struct __cilkrts_pedigree *)pthread_getspecific(pedigree_leaf_key);
+    }
+    else {
+        return 0;
+    }
+    
+    if (!pedigree_tls && create_new) {
+        // This call creates two nodes, X and Y.
+        // X == pedigree_tls[0] is the leaf node, which gets copied
+        // in and out of a user worker w when w binds and unbinds.
+        // Y == pedigree_tls[1] is the root node,
+        // which is a constant node that represents the user worker
+        // thread w.
+       pedigree_tls = (__cilkrts_pedigree*)
+           __cilkrts_malloc(2 * sizeof(__cilkrts_pedigree));
+
+        // This call sets the TLS pointer to the new node.
+       __cilkrts_set_tls_pedigree_leaf(pedigree_tls);
+        
+        pedigree_tls[0].rank = 0;
+        pedigree_tls[0].parent = &pedigree_tls[1];
+
+        // Create Y, whose rank begins as the global counter value.
+        pedigree_tls[1].rank =
+            __sync_add_and_fetch(&__cilkrts_global_pedigree_tls_counter, 1);
+
+        pedigree_tls[1].parent = NULL;
+        CILK_ASSERT(pedigree_tls[1].rank != -1);
+    }
+    return pedigree_tls;
+}
+
+#if SUPPORT_GET_CURRENT_FIBER > 0
+COMMON_SYSDEP
+cilk_fiber_sysdep* cilkos_get_tls_cilk_fiber(void)
+{
+    if (__builtin_expect(cilk_keys_defined, 1))
+        return (cilk_fiber_sysdep *)pthread_getspecific(fiber_key);
+    else
+        return NULL;
+}
+#endif
+
+COMMON_SYSDEP
+void __cilkrts_set_tls_worker(__cilkrts_worker *w)
+{
+    if (__builtin_expect(cilk_keys_defined, 1)) {
+        int status;
+        status = pthread_setspecific(worker_key, w);
+        CILK_ASSERT (status == 0);
+        return;
+    }
+    else
+    {
+        serial_worker = w;
+    }
+}
+
+COMMON_SYSDEP
+void __cilkrts_set_tls_tbb_interop(__cilk_tbb_stack_op_thunk *t)
+{
+    if (__builtin_expect(cilk_keys_defined, 1)) {
+        int status;
+        status = pthread_setspecific(tbb_interop_key, t);
+        CILK_ASSERT (status == 0);
+        return;
+    }
+    abort();
+}
+
+COMMON_SYSDEP
+void __cilkrts_set_tls_pedigree_leaf(__cilkrts_pedigree* pedigree_leaf)
+{
+    if (__builtin_expect(cilk_keys_defined, 1)) {
+        int status;
+        status = pthread_setspecific(pedigree_leaf_key, pedigree_leaf);
+        CILK_ASSERT (status == 0);
+        return;
+    }
+    abort();
+}
+
+#if SUPPORT_GET_CURRENT_FIBER > 0
+COMMON_SYSDEP
+void cilkos_set_tls_cilk_fiber(cilk_fiber_sysdep* fiber)
+{
+    if (__builtin_expect(cilk_keys_defined, 1)) {
+        int status;
+        status = pthread_setspecific(fiber_key, fiber);
+        CILK_ASSERT (status == 0);
+        return;
+    }
+    abort();
+}
+#endif
+
+#else
+void __cilkrts_init_tls_variables(void)
+{
+}
+#endif
+
+#if defined (__linux__) && ! defined(ANDROID)
+/*
+ * Get the thread id, rather than the pid. In the case of MIC offload, it's
+ * possible that we have multiple threads entering Cilk, and each has a
+ * different affinity.
+ */
+static pid_t linux_gettid(void)
+{
+    return syscall(SYS_gettid);
+}
+
+/*
+ * On Linux we look at the thread affinity mask and restrict ourself to one
+ * thread for each of the hardware contexts to which we are bound.
+ * Therefore if user does
+ * % taskset 0-1 cilkProgram
+ *       # restrict execution to hardware contexts zero and one
+ * the Cilk program will only use two threads even if it is running on a
+ * machine that has 32 hardware contexts.
+ * This is the right thing to do, because the threads are restricted to two
+ * hardware contexts by the affinity mask set by taskset, and if we were to
+ * create extra threads they would simply oversubscribe the hardware resources
+ * we can use.
+ * This is particularly important on MIC in offload mode, where the affinity
+ * mask is set by the offload library to force the offload code away from
+ * cores that have offload support threads running on them.
+ */
+static int linux_get_affinity_count (int tid) 
+{
+    cpu_set_t process_mask;
+
+    // Extract the thread affinity mask
+    int err = sched_getaffinity (tid, sizeof(process_mask),&process_mask);
+
+    if (0 != err)
+    {
+        return 0;
+    }
+
+    // We have extracted the mask OK, so now we can count the number of threads
+    // in it.  This is linear in the maximum number of CPUs available, We
+    // could do a logarithmic version, if we assume the format of the mask,
+    // but it's not really worth it. We only call this at thread startup
+    // anyway.
+    int available_procs = 0;
+    int i;
+    for (i = 0; i < CPU_SETSIZE; i++)
+    {
+        if (CPU_ISSET(i, &process_mask))
+        {
+            available_procs++;
+        }
+    }
+
+    return available_procs;
+}
+#endif
+
+/*
+ * __cilkrts_hardware_cpu_count
+ *
+ * Returns the number of available CPUs on this hardware.  This is architecture-
+ * specific. 
+ */
+
+COMMON_SYSDEP int __cilkrts_hardware_cpu_count(void)
+{
+#if defined ANDROID
+    return sysconf (_SC_NPROCESSORS_ONLN);
+#elif defined __MIC__
+    /// HACK: Usually, the 3rd and 4th hyperthreads are not beneficial
+    /// on KNC.  Also, ignore the last core.
+    int P = sysconf (_SC_NPROCESSORS_ONLN);
+    return P/2 - 2;
+#elif defined __linux__
+    int affinity_count = linux_get_affinity_count(linux_gettid());
+
+    return (0 != affinity_count) ? affinity_count : sysconf (_SC_NPROCESSORS_ONLN);
+#elif defined __APPLE__
+    int count = 0;
+    int cmd[2] = { CTL_HW, HW_NCPU };
+    size_t len = sizeof count;
+    int status = sysctl(cmd, 2, &count, &len, 0, 0);
+    assert(status >= 0);
+    assert((unsigned)count == count);
+
+    return count;
+#elif defined  __FreeBSD__ || defined __CYGWIN__
+    int ncores = sysconf(_SC_NPROCESSORS_ONLN);
+
+    return ncores;
+    // Just get the number of processors
+//    return sysconf(_SC_NPROCESSORS_ONLN);
+#elif defined  __VXWORKS__
+    return __builtin_popcount( vxCpuEnabledGet() );
+#else
+#error "Unknown architecture"
+#endif
+}
+
+COMMON_SYSDEP void __cilkrts_sleep(void)
+{
+#ifdef __VXWORKS__
+       taskDelay(1);
+#else                  
+    usleep(1);
+#endif 
+}
+
+COMMON_SYSDEP void __cilkrts_yield(void)
+{
+#if __APPLE__ || __FreeBSD__ || __VXWORKS__
+    // On MacOS, call sched_yield to yield quantum.  I'm not sure why we
+    // don't do this on Linux also.
+    sched_yield();
+#elif defined(__MIC__)
+    // On MIC, pthread_yield() really trashes things.  Arch's measurements
+    // showed that calling _mm_delay_32() (or doing nothing) was a better
+    // option.  Delaying 1024 clock cycles is a reasonable compromise between
+    // giving up the processor and latency starting up when work becomes
+    // available
+    _mm_delay_32(1024);
+#elif defined(ANDROID)
+    // On Android, call sched_yield to yield quantum.  I'm not sure why we
+    // don't do this on Linux also.
+    sched_yield();
+#else
+    // On Linux, call pthread_yield (which in turn will call sched_yield)
+    // to yield quantum.
+    pthread_yield();
+#endif
+}
+
+COMMON_SYSDEP __STDNS size_t cilkos_getenv(char* value, __STDNS size_t vallen,
+                                           const char* varname)
+{
+    CILK_ASSERT(value);
+    CILK_ASSERT(varname);
+
+    const char* envstr = getenv(varname);
+    if (envstr)
+    {
+        size_t len = strlen(envstr);
+        if (len > vallen - 1)
+            return len + 1;
+
+        strcpy(value, envstr);
+        return len;
+    }
+    else
+    {
+        value[0] = '\0';
+        return 0;
+    }
+}
+
+/*
+ * Unrecoverable error: Print an error message and abort execution.
+ */
+COMMON_SYSDEP void cilkos_error(const char *fmt, ...)
+{
+    va_list l;
+    fflush(NULL);
+    fprintf(stderr, "Cilk error: ");
+    va_start(l, fmt);
+    vfprintf(stderr, fmt, l);
+    va_end(l);
+    fprintf(stderr, "Exiting.\n");
+    fflush(stderr);
+
+    abort();
+}
+
+/*
+ * Print a warning message and return.
+ */
+COMMON_SYSDEP void cilkos_warning(const char *fmt, ...)
+{
+    va_list l;
+    fflush(NULL);
+    fprintf(stderr, "Cilk warning: ");
+    va_start(l, fmt);
+    vfprintf(stderr, fmt, l);
+    va_end(l);
+    fflush(stderr);
+}
+
+static void __attribute__((constructor)) init_once()
+{
+    /*__cilkrts_debugger_notification_internal(CILK_DB_RUNTIME_LOADED);*/
+    __cilkrts_init_tls_variables();
+}
+
+
+#define PAGE 4096
+#define CILK_MIN_STACK_SIZE (4*PAGE)
+// Default size for the stacks that we create in Cilk for Unix.
+#define CILK_DEFAULT_STACK_SIZE 0x100000
+
+/*
+ * Convert the user's specified stack size into a "reasonable" value
+ * for this OS.
+ */
+size_t cilkos_validate_stack_size(size_t specified_stack_size) {
+    // Convert any negative value to the default.
+    if (specified_stack_size == 0) {
+        CILK_ASSERT((CILK_DEFAULT_STACK_SIZE % PAGE) == 0);
+        return CILK_DEFAULT_STACK_SIZE;
+    }
+    // Round values in between 0 and CILK_MIN_STACK_SIZE up to
+    // CILK_MIN_STACK_SIZE.
+    if (specified_stack_size <= CILK_MIN_STACK_SIZE) {
+        return CILK_MIN_STACK_SIZE;
+    }
+    if ((specified_stack_size % PAGE) > 0) {
+        // Round the user's stack size value up to nearest page boundary.
+        return (PAGE * (1 + specified_stack_size / PAGE));
+    }
+    return specified_stack_size;
+}
+
+long cilkos_atomic_add(volatile long* p, long x)
+{
+    return __sync_add_and_fetch(p, x);
+}
+
+/* End os-unix.c */
diff --git a/libcilkrts/runtime/os.h b/libcilkrts/runtime/os.h
new file mode 100644 (file)
index 0000000..8066f03
--- /dev/null
@@ -0,0 +1,236 @@
+/* os.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file os.h
+ *
+ * @brief Low-level operating-system dependent facilities, not dependent on
+ * any Cilk facilities.
+ */
+
+#ifndef INCLUDED_OS_DOT_H
+#define INCLUDED_OS_DOT_H
+
+#include "rts-common.h"
+#include "cilk/common.h"
+#include "cilk-tbb-interop.h"
+
+#ifdef __cplusplus
+#   include <cstddef>
+#else
+#   include <stddef.h>
+#endif
+
+__CILKRTS_BEGIN_EXTERN_C
+
+
+// /* Thread-local storage */
+// #ifdef _WIN32
+// typedef unsigned cilkos_tls_key_t;
+// #else
+// typedef pthread_key_t cilkos_tls_key_t;
+// #endif
+// cilkos_tls_key_t cilkos_allocate_tls_key();
+// void cilkos_set_tls_pointer(cilkos_tls_key_t key, void* ptr);
+// void* cilkos_get_tls_pointer(cilkos_tls_key_t key);
+
+/* The RTS assumes that some thread-local state exists that stores the
+   worker and reducer map currently associated with a thread.  These routines
+   manipulate this state. */
+
+/** @brief Thread-local state for cilk fibers. */
+typedef struct cilk_fiber_sysdep cilk_fiber_sysdep;
+
+/** @brief Initialize  all TLS variables for Cilk. */
+COMMON_SYSDEP void __cilkrts_init_tls_variables(void);
+
+/** @brief Set worker struct in TLS. */
+COMMON_SYSDEP
+void __cilkrts_set_tls_worker(__cilkrts_worker *w) cilk_nothrow;
+
+/** @brief Get stack_op for TBB-interop structures from TLS. */
+COMMON_SYSDEP
+__cilk_tbb_stack_op_thunk *__cilkrts_get_tls_tbb_interop(void);
+
+/** @brief Set stack_op for TBB-interop structures in TLS. */
+COMMON_SYSDEP
+void __cilkrts_set_tls_tbb_interop(__cilk_tbb_stack_op_thunk *t);
+
+/**
+ * @brief Get the pointer to the pedigree leaf node from TLS.
+ *
+ * Function to get a pointer to the thread's pedigree leaf node.  This
+ * pointer can be NULL.
+ */
+COMMON_SYSDEP
+__cilkrts_pedigree * __cilkrts_get_tls_pedigree_leaf(int create_new);
+
+/**
+ * @brief Sets the pointer to the pedigree leaf node in TLS.
+ *
+ * If the previous pointer value was not NULL, it is the caller's
+ * responsibility to ensure that previous pointer value is saved and
+ * freed.
+ *
+ * @param pedigree_leaf The leaf node to store into TLS.
+ */ 
+COMMON_SYSDEP
+void __cilkrts_set_tls_pedigree_leaf(__cilkrts_pedigree* pedigree_leaf);
+
+
+#if SUPPORT_GET_CURRENT_FIBER > 0
+/**
+ * @brief Get the cilk_fiber from TLS. 
+ */
+COMMON_SYSDEP
+cilk_fiber_sysdep* cilkos_get_tls_cilk_fiber(void);
+
+/**
+ * @brief Set the cilk_fiber in TLS.
+ *
+ * @param fiber The fiber to store into TLS. 
+ */
+COMMON_SYSDEP
+void cilkos_set_tls_cilk_fiber(cilk_fiber_sysdep* fiber);
+#endif
+
+/**
+ * @brief Function for returning the current thread id.
+ * @warning This function is useful for debugging purposes only.
+ */
+COMMON_SYSDEP
+void* cilkos_get_current_thread_id(void);
+
+/** @brief Return number of CPUs supported by this hardware, using whatever definition
+   of CPU is considered appropriate. */
+COMMON_SYSDEP int __cilkrts_hardware_cpu_count(void);
+
+/** @brief Get current value of timer */
+COMMON_SYSDEP unsigned long long __cilkrts_getticks(void);
+
+/* Machine instructions */
+
+/// Stall execution for a few cycles.
+COMMON_SYSDEP void __cilkrts_short_pause(void);
+/// Wrapper for xchg instruction
+COMMON_SYSDEP int __cilkrts_xchg(volatile int *ptr, int x);
+
+// Defines __cilkrts_fence - A macro for x86, a function call for other
+// architectures
+#include "os-fence.h"
+
+COMMON_SYSDEP void __cilkrts_sleep(void); ///< Sleep briefly 
+COMMON_SYSDEP void __cilkrts_yield(void); ///< Yield quantum 
+
+/**
+ * @brief Gets environment variable 'varname' and copy its value into 'value'.
+ *
+ * If the entire value, including the null terminator fits into 'vallen'
+ * bytes, then returns the length of the value excluding the null.  Otherwise,
+ * leaves the contents of 'value' undefined and returns the number of
+ * characters needed to store the environment variable's value, *including*
+ * the null terminator.
+ *
+ * @param value    Buffer to store value.
+ * @param vallen   Length of value buffer
+ * @param varname  Name of the environment variable.
+ * @return         Length of value buffer (excluding the null).
+ */
+COMMON_SYSDEP __STDNS size_t cilkos_getenv(char* value, __STDNS size_t vallen,
+                                           const char* varname);
+
+/**
+ * @brief Unrecoverable error: Print an error message and abort execution.
+ */
+COMMON_SYSDEP void cilkos_error(const char *fmt, ...);
+
+/**
+ * @brief Print a warning message and return.
+ */
+COMMON_SYSDEP void cilkos_warning(const char *fmt, ...);
+
+/**
+ * @brief Convert the user's specified stack size into a "reasonable"
+ * value for the current OS.
+ *
+ * @param specified_stack_size   User-specified stack size.
+ * @return New stack size value, modified for the OS.
+ */
+COMMON_SYSDEP size_t cilkos_validate_stack_size(size_t specified_stack_size);
+
+/**
+ * @brief Atomic addition: computes *p += x.
+ * 
+ * @param p  Pointer to value to update
+ * @param x  Value of x.
+ */
+COMMON_SYSDEP long cilkos_atomic_add(volatile long* p, long x);
+
+#ifdef _WIN32
+
+/**
+ * @brief Windows-only low-level functions for processor groups.
+ */
+typedef struct _GROUP_AFFINITY GROUP_AFFINITY;
+
+/**
+ * @brief Probe the executing OS to see if it supports processor
+ * groups.  These functions are expected to be available in Windows 7
+ * or later.
+ */
+void win_init_processor_groups(void);
+
+unsigned long win_get_active_processor_count(unsigned short GroupNumber);
+unsigned short win_get_active_processor_group_count(void);
+int win_set_thread_group_affinity(/*HANDLE*/ void* hThread,
+                                  const GROUP_AFFINITY *GroupAffinity,
+                                  GROUP_AFFINITY* PreviousGroupAffinity);
+
+/**
+ * @brief Cleans up any state allocated in TLS.
+ *
+ * Only defined for Windows because Linux calls destructors for each
+ * thread-local variable.
+ */
+void __cilkrts_per_thread_tls_cleanup(void);
+
+#endif // _WIN32
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_OS_DOT_H)
diff --git a/libcilkrts/runtime/os_mutex-unix.c b/libcilkrts/runtime/os_mutex-unix.c
new file mode 100644 (file)
index 0000000..af398cd
--- /dev/null
@@ -0,0 +1,193 @@
+/* os_mutex-unix.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#include "os_mutex.h"
+#include "bug.h"
+
+#include <stdlib.h>
+#include <errno.h>
+#include <pthread.h>
+
+// contains notification macros for VTune.
+#include "cilk-ittnotify.h"
+
+/*
+ * OS Mutex functions.
+ *
+ * Not to be confused with the spinlock mutexes implemented in cilk_mutex.c
+ */
+
+struct os_mutex {
+    pthread_mutex_t mutex;  ///< On Linux, os_mutex is implemented with a pthreads mutex
+};
+
+// Unix implementation of the global OS mutex.  This will be created by the
+// first call to global_os_mutex_lock() and *NEVER* destroyed.  On gcc-based
+// systems there's no way to guarantee the ordering of constructors and
+// destructors, so we can't be guaranteed that our destructor for a static
+// object will be called *after* any static destructors that may use Cilk
+// in the user's application
+static struct os_mutex *global_os_mutex = NULL;
+
+/* Sometimes during shared library load malloc doesn't work.
+   To handle that case, preallocate space for one mutex. */
+static struct os_mutex static_mutex;
+static int static_mutex_used;
+
+struct os_mutex *__cilkrts_os_mutex_create(void)
+{
+    int status;
+    struct os_mutex *mutex = (struct os_mutex *)malloc(sizeof(struct os_mutex));
+    pthread_mutexattr_t attr;
+
+    ITT_SYNC_CREATE(mutex, "OS Mutex");
+
+    if (!mutex) {
+        if (static_mutex_used) {
+            __cilkrts_bug("Cilk RTS library initialization failed");
+        } else {
+            static_mutex_used = 1;
+            mutex = &static_mutex;
+        }
+    }
+
+    status = pthread_mutexattr_init(&attr);
+    CILK_ASSERT (status == 0);
+#if defined DEBUG || CILK_LIB_DEBUG 
+#ifdef PTHREAD_MUTEX_ERRORCHECK
+    status = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
+#else
+    status = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
+#endif
+    CILK_ASSERT (status == 0);
+#endif
+    status = pthread_mutex_init (&mutex->mutex, &attr);
+    CILK_ASSERT (status == 0);
+    pthread_mutexattr_destroy(&attr);
+
+    return mutex;
+}
+
+void __cilkrts_os_mutex_lock(struct os_mutex *p)
+{
+    int status;
+    status = pthread_mutex_lock (&p->mutex);
+    ITT_SYNC_ACQUIRED(p);
+    if (__builtin_expect(status, 0) == 0)
+        return;
+    if (status == EDEADLK)
+        __cilkrts_bug("Cilk runtime error: deadlock acquiring mutex %p\n",
+                      p);
+    else
+        __cilkrts_bug("Cilk runtime error %d acquiring mutex %p\n",
+                      status, p);
+}
+
+int __cilkrts_os_mutex_trylock(struct os_mutex *p)
+{
+    int status;
+    status = pthread_mutex_trylock (&p->mutex);
+    return (status == 0);
+}
+
+void __cilkrts_os_mutex_unlock(struct os_mutex *p)
+{
+    int status;
+    ITT_SYNC_RELEASING(p);
+    status = pthread_mutex_unlock (&p->mutex);
+    CILK_ASSERT(status == 0);
+}
+
+void __cilkrts_os_mutex_destroy(struct os_mutex *p)
+{
+    pthread_mutex_destroy (&p->mutex);
+    if (p == &static_mutex) {
+        static_mutex_used = 0;
+    } else {
+        free(p);
+    }
+}
+
+/*
+ * create_global_os_mutex
+ *
+ * Function used with pthread_once to initialize the global OS mutex.  Since
+ * pthread_once requires a function which takes no parameters and has no
+ * return value, the global OS mutex will be stored in the static (global
+ * to the compilation unit) variable "global_os_mutex."
+ * 
+ * 
+ * global_os_mutex will never be destroyed.
+ */
+static void create_global_os_mutex(void)
+{
+    CILK_ASSERT(NULL == global_os_mutex);
+    global_os_mutex = __cilkrts_os_mutex_create();
+}
+
+void global_os_mutex_lock(void)
+{
+    // pthread_once_t used with pthread_once to guarantee that
+    // create_global_os_mutex() is only called once
+    static pthread_once_t global_os_mutex_is_initialized = PTHREAD_ONCE_INIT;
+
+    // Execute create_global_os_mutex once in a thread-safe manner
+    // Note that create_global_os_mutex returns the mutex in the static
+    // (global to the module) variable "global_os_mutex"
+    pthread_once(&global_os_mutex_is_initialized,
+                create_global_os_mutex);
+
+    // We'd better have allocated a global_os_mutex
+    CILK_ASSERT(NULL != global_os_mutex);
+    
+    // Acquire the global OS mutex
+    __cilkrts_os_mutex_lock(global_os_mutex);
+}
+
+void global_os_mutex_unlock(void)
+{
+    // We'd better have allocated a global_os_mutex.  This means you should
+    // have called global_os_mutex_lock() before calling
+    // global_os_mutex_unlock(), but this is the only check for it.
+    CILK_ASSERT(NULL != global_os_mutex);
+
+    // Release the global OS mutex
+    __cilkrts_os_mutex_unlock(global_os_mutex);
+}
+
+/* End os_mutex-unix.c */
diff --git a/libcilkrts/runtime/os_mutex.h b/libcilkrts/runtime/os_mutex.h
new file mode 100644 (file)
index 0000000..71d9eb1
--- /dev/null
@@ -0,0 +1,135 @@
+/* os_mutex.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file os_mutex.h
+ *
+ * @brief Portable interface to operating-system mutexes.
+ *
+ * Do not confuse os_mutex with Cilk runtime-specific spinlock mutexes.
+ */
+
+#ifndef INCLUDED_OS_MUTEX_DOT_H
+#define INCLUDED_OS_MUTEX_DOT_H
+
+#include <cilk/common.h>
+#include "rts-common.h"
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/// Opaque type
+typedef struct os_mutex os_mutex;
+
+/**
+ * Allocate and initialize an os_mutex
+ *
+ * @return A pointer to the initialized os_mutex
+ */
+COMMON_SYSDEP os_mutex* __cilkrts_os_mutex_create(void);
+
+/**
+ * Acquire the os_mutex for exclusive use
+ *
+ * @param m The os_mutex that is to be acquired.
+ */
+COMMON_SYSDEP void __cilkrts_os_mutex_lock(os_mutex *m);
+
+/**
+ * Try to acquire the os_mutex.
+ *
+ * @param   m  The os_mutex to try to acquire
+ * @return  0      if the lock acquire failed
+ * @return nonzero if the lock was acquired
+ */
+COMMON_SYSDEP int __cilkrts_os_mutex_trylock(os_mutex *m);
+
+/**
+ * Release the os_mutex
+ *
+ * @param m The os_mutex that is to be released.
+ */
+COMMON_SYSDEP void __cilkrts_os_mutex_unlock(os_mutex *m);
+
+/**
+ * Release any resources and deallocate the os_mutex.
+ *
+ * @param m The os_mutex that is to be deallocated.
+ */
+COMMON_SYSDEP void __cilkrts_os_mutex_destroy(os_mutex *m);
+
+/**
+ * Acquire the global os_mutex for exclusive use.  The global os_mutex
+ * will be initialized the first time this function is called in a
+ * thread-safe manner.
+ */
+COMMON_SYSDEP void global_os_mutex_lock();
+
+/**
+ * Release the global os_mutex.  global_os_mutex_lock() must have been
+ * called first.
+ */
+COMMON_SYSDEP void global_os_mutex_unlock();
+
+
+#ifdef _MSC_VER
+
+/**
+ * @brief Create the global OS mutex - Windows only.
+ *
+ * On Windows we use DllMain() to create the global OS mutex when cilkrts20.dll
+ * is loaded. As opposed to Linux/MacOS where we use pthread_once to implement
+ * a singleton since there are no guarantees about constructor or destructor
+ * ordering between shared objects.
+ */
+NON_COMMON void global_os_mutex_create();
+
+/**
+ * @brief Destroy the global OS mutex - Windows only
+ *
+ * On Windows we use DllMain() to destroy the global OS mutex when
+ * cilkrts20.dll is unloaded.  As opposed to Linux/MacOS where we cannot
+ * know when it's safe to destroy the global OS mutex since there are no
+ * guarantees about constructor or destructor ordering.
+ */
+NON_COMMON void global_os_mutex_destroy();
+
+#endif  // _MSC_VER
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_OS_MUTEX_DOT_H)
diff --git a/libcilkrts/runtime/pedigrees.c b/libcilkrts/runtime/pedigrees.c
new file mode 100644 (file)
index 0000000..dee4d9c
--- /dev/null
@@ -0,0 +1,112 @@
+/* pedigrees.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2007-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+#include "pedigrees.h"
+#include "local_state.h"
+
+/*************************************************************
+  Pedigree API code.
+*************************************************************/
+
+/*
+ * C99 requires that every inline function with external linkage have one
+ * extern declaration in the program (with the inline definition in scope).
+ */
+COMMON_PORTABLE
+extern void update_pedigree_on_leave_frame(__cilkrts_worker *w,
+                                          __cilkrts_stack_frame *sf);
+
+void __cilkrts_set_pedigree_leaf(__cilkrts_pedigree *leaf)
+{
+    __cilkrts_set_tls_pedigree_leaf(leaf);
+}
+
+void load_pedigree_leaf_into_user_worker(__cilkrts_worker *w)
+{
+    __cilkrts_pedigree *pedigree_leaf;
+    CILK_ASSERT(w->l->type == WORKER_USER);
+    pedigree_leaf = __cilkrts_get_tls_pedigree_leaf(1);
+    w->pedigree = *pedigree_leaf;
+
+    // Save a pointer to the old leaf.
+    // We'll need to restore it later.
+    CILK_ASSERT(w->l->original_pedigree_leaf == NULL);
+    w->l->original_pedigree_leaf = pedigree_leaf;
+    
+    __cilkrts_set_tls_pedigree_leaf(&w->pedigree);
+    
+    // Check that this new pedigree root has at least two values.
+    CILK_ASSERT(w->pedigree.parent);
+    CILK_ASSERT(w->pedigree.parent->parent == NULL);
+}
+
+void save_pedigree_leaf_from_user_worker(__cilkrts_worker *w)
+{
+    CILK_ASSERT(w->l->type == WORKER_USER);
+
+    // Existing leaf in tls should be for the current worker.
+    // This assert is expensive to check though.
+    // CILK_ASSERT(&w->pedigree == __cilkrts_get_tls_pedigree_leaf(0));
+    CILK_ASSERT(w->l->original_pedigree_leaf);
+
+    // w should finish with a pedigree node that points to 
+    // the same root that we just looked up.
+
+    // TODO: This assert should be valid.
+    // But we are removing it now to make exceptions (without pedigrees) work.
+    // Currently, reading the pedigree after an exception is caught
+    // fails because the pedigree chain not restored correctly. 
+    // CILK_ASSERT(w->l->original_pedigree_leaf->next == w->pedigree.parent);
+    w->l->original_pedigree_leaf->rank = w->pedigree.rank;
+
+    // Save that leaf pointer back into tls.
+    __cilkrts_set_tls_pedigree_leaf(w->l->original_pedigree_leaf);
+    // Null out worker's leaf for paranoia.
+    w->l->original_pedigree_leaf = NULL;
+}
+
+
+
+/*
+  Local Variables: **
+  c-file-style:"bsd" **
+  c-basic-offset:4 **
+  indent-tabs-mode:nil **
+  End: **
+*/
diff --git a/libcilkrts/runtime/pedigrees.h b/libcilkrts/runtime/pedigrees.h
new file mode 100644 (file)
index 0000000..3f6ebb9
--- /dev/null
@@ -0,0 +1,130 @@
+/* pedigrees.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#ifndef INCLUDED_PEDIGREES_DOT_H
+#define INCLUDED_PEDIGREES_DOT_H
+
+
+#include <cilk/common.h>
+#include <internal/abi.h>
+
+#include "rts-common.h"
+#include "global_state.h"
+#include "os.h"
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * @file pedigrees.h
+ *
+ * @brief pedigrees.h declares common routines related to pedigrees
+ * and the pedigree API.
+ */
+
+
+/**
+ * @brief Sets the leaf pedigree node for the current user thread.
+ *
+ * A typical implementation stores this pedigree node in thread-local
+ * storage.
+ *
+ * Preconditions:
+ *  - Current thread should be a user thread.
+ *
+ * @param leaf The pedigree node to store as a leaf.
+ */
+COMMON_PORTABLE
+void __cilkrts_set_pedigree_leaf(__cilkrts_pedigree* leaf);
+
+
+/**
+ * Load the pedigree leaf node from thread-local storage into the
+ * current user worker.  This method should execute as a part of
+ * binding the user thread to a worker.
+ *
+ * Preconditions:
+ *  
+ *  - w should be the worker for the current thread 
+ *  - w should be a user thread.
+ */
+COMMON_PORTABLE
+void load_pedigree_leaf_into_user_worker(__cilkrts_worker *w);
+
+/**
+ * Save the pedigree leaf node from the worker into thread-local
+ * storage.  This method should execute as part of unbinding a user
+ * thread from a worker.
+ *
+ * Preconditions:
+ *  
+ *  - w should be the worker for the current thread 
+ *  - w should be a user thread.
+ */
+COMMON_PORTABLE
+void save_pedigree_leaf_from_user_worker(__cilkrts_worker *w);
+
+
+
+/**
+ * Update pedigree for a worker when leaving a frame.
+ *
+ * If this is the frame of a spawn helper (indicated by the
+ *  CILK_FRAME_DETACHED flag) we must update the pedigree.  The
+ *  pedigree points to nodes allocated on the stack.  Failing to
+ *  update it will result in a accvio/segfault if the pedigree is
+ *  walked.  This must happen for all spawn helper frames, even if
+ *  we're processing an exception.
+ */ 
+COMMON_PORTABLE
+inline void update_pedigree_on_leave_frame(__cilkrts_worker *w,
+                                          __cilkrts_stack_frame *sf) 
+{
+    // Update the worker's pedigree information if this is an ABI 1 or later
+    // frame
+    if (CILK_FRAME_VERSION_VALUE(sf->flags) >= 1)
+    {
+       w->pedigree.rank = sf->spawn_helper_pedigree.rank + 1;
+       w->pedigree.parent = sf->spawn_helper_pedigree.parent;
+    }
+}
+
+
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_PEDIGREES_DOT_H)
diff --git a/libcilkrts/runtime/record-replay.cpp b/libcilkrts/runtime/record-replay.cpp
new file mode 100644 (file)
index 0000000..bc5a79f
--- /dev/null
@@ -0,0 +1,770 @@
+/* record-replay.cpp                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2012-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+/*
+ * Implementation of the record/replay functionality for Cilk Plus
+ */
+
+#include <cstring>
+#include <vector>
+#include <stdlib.h>
+
+// clang is really strict about printf formats, so use the annoying integer
+// printf macros.  Unfortunately they're not avaiable on Windows
+#ifdef _WIN32
+#define PRIu64 "llu"
+#else
+#define __STDC_FORMAT_MACROS 1
+#include <inttypes.h>
+#endif
+
+#include "record-replay.h"
+#include "bug.h"
+#include "internal/abi.h"
+#include "local_state.h"
+#include "full_frame.h"
+#include "global_state.h"
+#include "cilk_malloc.h"
+#include "os.h"  // for cilkos_error()
+
+#if RECORD_ON_REPLAY
+#pragma message ("*** Record on Replay is enabled!")
+#endif
+
+// Defined to write sequence number to the logs.  Note that you cannot
+// diff logs with sequence numbers because the numbers may increment in
+// different orders.
+//#define INCLUDE_SEQUENCE_NUMBER 1
+
+const int PED_VERSION = 1;      // Log recording version
+
+// Log types
+enum ped_type_t
+{
+    ped_type_unknown,
+    ped_type_steal,
+    ped_type_sync,
+    ped_type_orphaned,
+    ped_type_last               // Flags end of the list
+};
+
+// Log type strings
+#define PED_TYPE_STR_STEAL "Steal"
+#define PED_TYPE_STR_SYNC "Sync"
+#define PED_TYPE_STR_WORKERS "Workers"
+#define PED_TYPE_STR_ORPHANED "Orphaned"
+
+#define PED_TYPE_SIZE 16        // Buffer size for the type of pedigree.  Must
+                                // hold largest pedigree record type string.
+#define PEDIGREE_BUFF_SIZE 512  // Buffer size for the string representation
+                                // of a pedigree.
+
+/**
+ * Data we store for a replay log entry
+ */
+typedef struct replay_entry_t
+{
+    uint64_t *m_reverse_pedigree;   /**< Reverse pedigree for replay log entry */
+    ped_type_t m_type;              /**< Type of replay log entry */
+    int16_t m_pedigree_len;         /**< Number of terms in reverse pedigree */
+    int16_t m_value;                /**< Victim for STEALs, 0 if matching steal found for ORPHANs */
+
+   /**
+    * Load data read from the log into the entry
+    */
+    bool load(const char *type, const char *pedigee_str, int32_t value1, int32_t value2)
+    {
+        // Convert the type into an enum
+        if (0 == strcmp(type, PED_TYPE_STR_STEAL))
+        {
+            m_type = ped_type_steal;
+            m_value = (int16_t)value1;   // Victim
+        }
+        else
+        {
+            m_value = -1;      // Victim not valid
+            if (0 == strcmp(type, PED_TYPE_STR_SYNC))
+                m_type = ped_type_sync;
+            else if (0 == strcmp(type, PED_TYPE_STR_ORPHANED))
+                m_type = ped_type_orphaned;
+            else
+            {
+                m_type = ped_type_unknown;
+                return false;
+            }
+        }
+
+        // Parse the pedigree
+        m_pedigree_len = 0;
+
+        const char *p = pedigee_str;
+        char *end;
+
+        uint64_t temp_pedigree[PEDIGREE_BUFF_SIZE/2];
+
+        while(1)
+        {
+            temp_pedigree[m_pedigree_len++] = (uint64_t)strtol(p, &end, 10);
+            if ('\0' == *end)
+                break;
+            p = end + 1;
+        }
+
+        // Allocate memory to hold the pedigree.
+        // Copy the pedigree in reverse order since that's the order we'll
+        // traverse it
+        m_reverse_pedigree =
+            (uint64_t *)__cilkrts_malloc(sizeof(int64_t) * m_pedigree_len);
+        for (int n = 0; n < m_pedigree_len; n++)
+            m_reverse_pedigree[n] = temp_pedigree[(m_pedigree_len - 1) - n];
+
+        return true;
+    }
+
+   /**
+    * Match this entry against the data supplied.  This includes walking the
+    * pedigree from the specified node.
+    */
+    bool match (ped_type_t type, const __cilkrts_pedigree *node, int victim = -1)
+    {
+        int i = 0;
+
+        // If the type isn't what they're seeking, we don't have a match
+        if (type != m_type)
+            return false;
+
+        // If we're looking for a STEAL, then the victim must match
+        if ((type == ped_type_steal) && (victim != m_value))
+            return false;
+
+        // Compare the current pedigree against what was recorded
+        while ((NULL != node) && (i < m_pedigree_len))
+        {
+            // If we've got a pedigree rank difference, then we don't have
+            // a match
+            if (node->rank != m_reverse_pedigree[i])
+                return false;
+            node = node->parent;
+            i++;
+        }
+
+        // Make sure we exhausted both the pedigree chain and the recorded
+        // pedigree
+        return ((NULL == node) && (i == m_pedigree_len));
+    }
+
+   /**
+    * Advance to the next entry, skipping any ORPHANED records we didn't see
+    * a matching STEAL for
+    */
+    replay_entry_t *next_entry()
+    {
+        replay_entry_t *entry = this;
+
+        // You can't go beyond the end
+        if (ped_type_last == entry->m_type)
+            return entry;
+
+        // Advance to the next entry
+        entry++;
+
+        // Skip any ORPHANED records that don't have a matching steal. We
+        // initialized the value field to -1 for ORPHANED.  After loading all
+        // the log data, we iterated through all the STEAL records setting the
+        // matching ORPHANED record's value field to 0. So if an ORPHANED
+        // record's value field is still -1, it doesn't have a matching STEAL
+        // record, and I don't know why we chose not to return from the
+        // spawned function.
+        while ((ped_type_orphaned == entry->m_type) && (-1 == entry->m_value))
+        {
+            entry++;
+        }
+
+        return entry;
+    }
+
+   /**
+    * Release any allocated resources
+    */
+    void unload()
+    {
+        __cilkrts_free(m_reverse_pedigree);
+        m_reverse_pedigree = NULL;
+    }
+
+} replay_entry_t;
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * Walk the pedigree and generate a string representation with underscores
+ * between terms.  Currently does a recursive walk to generate a forward
+ * pedigree.
+ *
+ * @param p The buffer that is to be filled.  Assumed to be PEDIGREE_BUFF_SIZE
+ * characters long
+ * @param pnode The initial pedigree term to be written.
+ *
+ * @return A pointer into the pedigree string buffer after a term has been
+ * written.
+ */
+static
+char * walk_pedigree_nodes(char *p, const __cilkrts_pedigree *pnode)
+{
+    CILK_ASSERT(pnode);
+    if (pnode->parent)
+    {
+        p = walk_pedigree_nodes(p, pnode->parent);
+        p += sprintf(p, "_");
+    }
+
+    return p + sprintf(p, "%" PRIu64, pnode->rank);
+}
+
+/**
+ * Write a record to a replay log file.
+ *
+ * @param w The worker we're writing the pedigree for.
+ * @param type The type of the pedigree record, as a string
+ * @param initial_node The initial pedigree node to be written, or NULL if
+ * there is no pedigree for this record type.
+ * @param i1 First integer value to be written to the record.
+ * @param i2 Second integer value to be written to the record. Only applies
+ * to STEAL records. Defaults to -1 (unused).  The second value is always
+ * written to make parsing easier.
+ */
+static
+void write_to_replay_log (__cilkrts_worker *w, const char *type,
+                          const __cilkrts_pedigree *initial_node,
+                          int i1 = -1, int i2 = -1)
+{
+    char pedigree[PEDIGREE_BUFF_SIZE];
+
+    // If we don't have an initial pedigree node, just use "0" to fill the slot
+    if (NULL == initial_node)
+        strcpy(pedigree, "0");
+    else
+        walk_pedigree_nodes(pedigree, initial_node);
+
+#ifndef INCLUDE_SEQUENCE_NUMBER
+    // Simply write the record
+    fprintf(w->l->record_replay_fptr, "%s %s %d %d\n",
+            type, pedigree, i1, i2);
+#else
+    // Write the record with a sequence number.  The sequence number should
+    // always be the last term, and ignored on read
+
+    static long volatile seq_num = 0;
+    long write_num;
+
+    // Atomic increment functions are compiler/OS-specific
+#ifdef _WIN32
+    write_num = _InterlockedIncrement(&seq_num);
+#else /* GCC */
+    write_num = __sync_add_and_fetch(&seq_num, 1);
+#endif // _WIN32
+
+    fprintf(w->l->record_replay_fptr, "%s %s %d %d %ld\n",
+            type, pedigree, i1, i2, write_num);
+#endif // INCLUDE_SEQUENCE_NUMBER
+
+    fflush(w->l->record_replay_fptr);
+}
+
+/**
+ * Record data for a successful steal.
+ *
+ * The pedigree for a STEAL record is the pedigree of the stolen frame.
+ *
+ * @note It's assumed that replay_record_steal() has already checked that we're
+ * recording a log and that the record/replay functionality has not been
+ * compiled out.
+ *
+ * @param w The worker stealing a frame.
+ * @param victim_id The ID of the worker which had it's frame stolen.
+ */
+void replay_record_steal_internal(__cilkrts_worker *w, int32_t victim_id)
+{
+    // Follow the pedigree chain using worker's stack frame
+    CILK_ASSERT(w->l->next_frame_ff);
+    CILK_ASSERT(w->l->next_frame_ff->call_stack);
+
+    // Record steal: STEAL pedigree victim_id thief_id
+    write_to_replay_log (w, PED_TYPE_STR_STEAL,
+                         &(w->l->next_frame_ff->call_stack->parent_pedigree),
+                         victim_id);
+}
+
+/**
+ * Record data for the worker that continues from a sync
+ *
+ * The pedigree for a SYNC record is the pedigree at the sync.
+ *
+ * @note It's assumed that replay_record_sync() has already checked that we're
+ * recording a log and that the record/replay functionality has not been
+ * compiled out.
+ *
+ * @param w The worker continuing from a sync.
+ */
+void replay_record_sync_internal(__cilkrts_worker *w)
+{
+    // Record sync: SYNC pedigree last_worker_id
+    write_to_replay_log (w, PED_TYPE_STR_SYNC, &w->pedigree);
+}
+
+/**
+ * Record the pedigree of an attempt to return to a stolen parent
+ *
+ * The pedigree for an ORPHANED record is the pedigree of our parent
+ *
+ * @note It's assumed that replay_record_orphaned() has already checked that
+ * we're recording a log and that the record/replay functionality has not
+ * been compiled out.
+ *
+ * @param w The worker continuing noting that it has been orphaned.
+ */
+void replay_record_orphaned_internal(__cilkrts_worker *w)
+{
+    // Record steal: ORPHANED pedigree self
+    write_to_replay_log (w, PED_TYPE_STR_ORPHANED, w->pedigree.parent);
+}
+
+/**
+ * Attempt to match a SYNC record.  We have a match when this worker was
+ * recorded returning from the current call to __cilkrts_sync() with the
+ * same pedigree and this was the worker that continued from the sync, since
+ * it was the last to sync.
+ *
+ * If we find a match, the caller is expected to stall it is the last worker
+ * to reach a sync so it will be the worker to continue from the sync.
+ *
+ * @note It's assumed that replay_match_sync_pedigree() has already returned
+ * if we're not replaying a log, or if record/replay functionality has
+ * been compiled out.
+ *
+ * @param w The worker we're checking to see if we've got a match
+ */
+int replay_match_sync_pedigree_internal(__cilkrts_worker *w)
+{
+    // Return true if we have a match
+    if (w->l->replay_list_entry->match(ped_type_sync, &w->pedigree))
+        return 1;
+    else
+        return 0;
+}
+
+/**
+ * Advance to the next log entry from a SYNC record.  Consume the current
+ * SYNC record on this worker and advance to the next one.
+ *
+ * @note It's assumed that replay_advance_from_sync() has already returned if
+ * we're not replaying a log, or if record/replay functionality has been
+ * compiled out.
+ *
+ * @param w The worker whose replay log we're advancing.
+ */
+void replay_advance_from_sync_internal (__cilkrts_worker *w)
+{
+    // The current replay entry must be a SYNC
+    CILK_ASSERT(ped_type_sync == w->l->replay_list_entry->m_type);
+
+    // Advance to the next entry
+    w->l->replay_list_entry = w->l->replay_list_entry->next_entry();
+}
+
+/**
+ * Called from random_steal() to override the ID of the randomly chosen victim
+ * worker which this worker will attempt to steal from. Returns the worker id
+ * of the next victim this worker was recorded stealing from, or -1 if the
+ * next record in the log is not a STEAL.
+ *
+ * @note This call does NOT attempt to match the pedigree.  That will be done
+ * by replay_match_victim_pedigree() after random_steal() has locked the victim
+ * worker.
+ *
+ * @param w The __cilkrts_worker we're executing on.  The worker's replay log
+ * is checked for a STEAL record.  If we've got one, the stolen worker ID is
+ * returned.
+ *
+ * @return -1 if the next record is not a STEAL
+ * @return recorded stolen worker ID if we've got a matching STEAL record
+ */
+int replay_get_next_recorded_victim_internal(__cilkrts_worker *w)
+{
+    // If the next record isn't a STEAL, abort the attempt to steal work
+    if (ped_type_steal != w->l->replay_list_entry->m_type)
+        return -1;
+
+    // Return the victim's worker ID from the STEAL record.  We'll check
+    // the pedigree after random_steal has locked the victim worker.
+    return w->l->replay_list_entry->m_value;
+}
+
+/**
+ * Called from random_steal() to determine if we have a STEAL record that
+ * matches the pedigree at the head of the victim worker.  If we do have a
+ * match, the STEAL record is consumed.
+ *
+ * @note It's assumed that replay_match_victim_pedigree() has already returned if
+ * we're not replaying a log, or if record/replay functionality has been
+ * compiled out.
+ *
+ * @return 1 if we have a match
+ * @return 0 if the current replay record isn't a STEAL record, or the victim
+ * isn't correct, or the pedigree doesn't match.
+ */
+int replay_match_victim_pedigree_internal(__cilkrts_worker *w, __cilkrts_worker *victim)
+{
+    // If we don't have a match, return 0
+    if (! w->l->replay_list_entry->match(ped_type_steal,
+                                             &((*victim->head)->parent_pedigree),
+                                             victim->self))
+        return 0;
+
+    // Consume this entry
+    w->l->replay_list_entry = w->l->replay_list_entry->next_entry();
+
+    // Return success
+    return 1;
+}
+
+/**
+ * If the frame we're about to return to was recorded as being stolen,
+ * stall until it is.
+ *
+ * @note It's assumed that replay_wait_for_steal_if_parent_was_stolen() has
+ * already returned if we're not replaying a log, or if record/replay
+ * functionality has been compiled out.
+ *
+ * @param w The worker we're executing on.
+ */
+void replay_wait_for_steal_if_parent_was_stolen_internal(__cilkrts_worker *w)
+{
+    // If our parent wasn't recorded orphanen, return now
+    if (! w->l->replay_list_entry->match (ped_type_orphaned,
+                                              w->pedigree.parent))
+        return;
+
+    // Stall until our parent is stolen.  Note that we're comparing head
+    // and tail, not head and exc.  The steal is not completed until tail
+    // is modified.
+    while (!((w->tail - 1) < w->head))
+        __cilkrts_sleep();
+
+    // Consume the entry
+    w->l->replay_list_entry = w->l->replay_list_entry->next_entry();
+}
+
+/**
+ * Allocate memory for the list of logged events.
+ *
+ * This function will read through the file and count the number of records
+ * so it can estimate how big a buffer to allocate for the array or replay
+ * entries.  It will then rewind the file to the beginning so it can be
+ * loaded into memory.
+ *
+ * @param w The worker we're loading the file for.
+ * @param f The file of replay data we're scanning.
+ */
+static
+void allocate_replay_list(__cilkrts_worker *w, FILE *f)
+{
+    // Count the number of entries - yeah, it's a hack, but it lets me
+    // allocate the space all at once instead of in chunks
+    char buf[1024];
+    int entries = 1;    // Include "LAST" node
+
+    while (! feof(f))
+    {
+        if (fgets(buf, 1024, f))
+        {
+            // Skip the Workers record - should only be in file for Worker 0
+            if (0 != strncmp(PED_TYPE_STR_WORKERS, buf, sizeof(PED_TYPE_STR_WORKERS)-1))
+                entries++;
+        }
+    }
+
+    w->l->replay_list_root =
+        (replay_entry_t *)__cilkrts_malloc(entries * sizeof(replay_entry_t));
+    w->l->replay_list_root[entries - 1].m_type = ped_type_last;
+
+    // Reset the file to the beginning
+    rewind(f);
+}
+
+/**
+ * Load the replay log for a worker into memory.
+ *
+ * @param w The worker we're loading the replay for.
+ */
+static
+void load_recorded_log(__cilkrts_worker *w)
+{
+    char ped_type[PED_TYPE_SIZE];
+    char ped_str[PEDIGREE_BUFF_SIZE];
+    int32_t i1 = -1, i2 = -1;
+    int fret;
+    char local_replay_file_name[512];
+    FILE *f;
+
+    // Open the log for reading
+    sprintf(local_replay_file_name, "%s%d.cilklog", w->g->record_replay_file_name,  w->self);
+    f = fopen(local_replay_file_name, "r");
+
+    // Make sure we found a log!
+    CILK_ASSERT (NULL != f);
+
+    // Initialize the replay_list
+    allocate_replay_list(w, f);
+    replay_entry_t *entry = w->l->replay_list_root;
+
+    // Read the data out and add it to our tables
+    while (! feof(f))
+    {
+#ifndef INCLUDE_SEQUENCE_NUMBER
+        fret = fscanf(f, "%s %s %d %d\n", ped_type, ped_str, &i1, &i2);
+        if(EOF == fret)
+            break;
+
+        // We must have read 4 fields
+        CILK_ASSERT(4 == fret);
+#else
+        int32_t write_num;
+        fret = fscanf(f, "%s %s %d %d %d\n", ped_type, ped_str,
+                      &i1, &i2, &write_num);
+        if(EOF == fret)
+            break;
+
+        // We must have read 5 fields
+        CILK_ASSERT(5 == fret);
+#endif // INCLUDE_SEQUENCE_NUMBER
+
+        // Load the data into the entry
+        if (0 == strcmp(ped_type, PED_TYPE_STR_WORKERS))
+        {
+            // Verify we're replaying with the same number of workers we recorded with
+            if (i1 != w->g->P)
+            {
+                // Fatal error - does not return
+                cilkos_error("Cannot continue replay: number of workers(%d) doesn't match "
+                             "that from the recording(%d).\n", w->g->P, i1);
+            }
+
+            // Verify that we understand this version of the pedigree file
+            if (PED_VERSION != i2)
+            {
+                // Fatal error - does not return
+                cilkos_error("Pedigree file version %d doesn't match current "
+                             "version %d - cannot continue.\n",
+                             i2, PED_VERSION);
+            }
+        }
+        else
+        {
+            entry->load(ped_type, ped_str, i1, i2);
+            entry++;
+        }
+    }
+
+    // Make sure we've filled the allocated memory.  We initialized the last
+    // entry in 
+    CILK_ASSERT(ped_type_last == entry->m_type);
+    w->l->replay_list_entry = w->l->replay_list_root;
+
+    // Close the log and return
+    fclose(f);
+}
+
+/**
+ * Scan a recorded log to match STEALs againsted ORPHANED records.
+ *
+ * @param g Cilk Runtime global state.  Passed to access the worker array so
+ * we can scan a worker's ORPHANED entries for one that matches a STEAL entry.
+ * @param entry The root of a replay_list for a worker.
+ */
+static
+void scan_for_matching_steals(global_state_t *g, replay_entry_t *entry)
+{
+    // Iterate over all of the entries
+    while (ped_type_last != entry->m_type)
+    {
+        // Look for STEALs.  That will tell us which worker the frame was
+        // stolen from
+        if (ped_type_steal == entry->m_type)
+        {
+            bool found = false;
+
+            // Validate the worker ID and make sure we've got a list
+            CILK_ASSERT((entry->m_value >= 0) && (entry->m_value < g->total_workers));
+            replay_entry_t *victim_entry = g->workers[entry->m_value]->l->replay_list_root;
+            CILK_ASSERT(NULL != victim_entry);
+
+            // Scan the victim's list for the matching ORPHANED record
+            while ((ped_type_last != victim_entry->m_type) && ! found)
+            {
+                if (ped_type_orphaned == victim_entry->m_type)
+                {
+                    if (entry->m_pedigree_len == victim_entry->m_pedigree_len)
+                    {
+                        if (0 == memcmp(entry->m_reverse_pedigree,
+                                        victim_entry->m_reverse_pedigree,
+                                        entry->m_pedigree_len * sizeof(int64_t)))
+                        {
+                            // Note that this ORPHANED record has a matching steal
+                            victim_entry->m_value = 0;
+                            found = true;
+                        }
+                    }
+                }
+                victim_entry++;
+            }
+        }
+        entry++;
+    }
+}
+
+
+/*
+ * Initialize per-worker data for record or replay - See record-replay.h
+ * for full routine header.
+ */
+void replay_init_workers(global_state_t *g)
+{
+    int i;
+    char worker_file_name[512];
+
+    // If we're not recording or replaying a log, we're done.  All of the
+    // fields in the global_state_t or local_state_t are already initialized
+    // to default values.
+    if (RECORD_REPLAY_NONE == g->record_or_replay)
+        return;
+
+    // If we're replaying a log, read each worker's log and construct the
+    // in-memory log
+    if (REPLAY_LOG == g->record_or_replay)
+    {
+        // Read all of the data
+        for (i = 0; i < g->total_workers; ++i)
+        {
+            // This function will also initialize and fill the worker's 
+            // replay list
+            load_recorded_log(g->workers[i]);
+        }
+
+        // Scan for orphans with no matching steal.  Mark them so they'll be
+        // skipped as we advance through the log.
+        for (i = 0; i < g->total_workers; ++i)
+        {
+            scan_for_matching_steals(g, g->workers[i]->l->replay_list_root);
+        }
+
+        // If we're recording the logs while replaying, create the log files.
+        // This will only be used for debugging.  Create the logs in the
+        // current directory.  It should be as good a place as any...
+#if RECORD_ON_REPLAY
+        for(i = 0; i < g->total_workers; ++i)
+        {
+            __cilkrts_worker *w = g->workers[i];
+            sprintf(worker_file_name, "replay_log_%d.cilklog",  w->self);
+            w->l->record_replay_fptr = fopen(worker_file_name, "w+");
+            CILK_ASSERT(NULL != w->l->record_replay_fptr);
+        }
+
+        // Record the number of workers, file version in Worker 0's file
+        write_to_replay_log (g->workers[0], PED_TYPE_STR_WORKERS, NULL, g->P, PED_VERSION);
+#endif // RECORD_ON_REPLAY
+    }
+
+    // If we're recording, create the log files
+    if (RECORD_LOG == g->record_or_replay)
+    {
+        for(i = 0; i < g->total_workers; ++i)
+        {
+            __cilkrts_worker *w = g->workers[i];
+            sprintf(worker_file_name, "%s%d.cilklog",
+                    g->record_replay_file_name,
+                    w->self);
+            w->l->record_replay_fptr = fopen(worker_file_name, "w+");
+            CILK_ASSERT(NULL != w->l->record_replay_fptr);
+        }
+
+        // Record the number of workers, file version in Worker 0's file
+        write_to_replay_log (g->workers[0], PED_TYPE_STR_WORKERS, NULL, g->P, PED_VERSION);
+    }
+}
+
+/*
+ * Do any necessary cleanup for the logs - See record-replay.h for full
+ * routine header.
+ */
+void replay_term(global_state_t *g)
+{
+    // Free memory for the record/replay log file name, if we've got one
+    if (g->record_replay_file_name)
+        __cilkrts_free(g->record_replay_file_name);
+
+    // Per-worker cleanup
+    for(int i = 0; i < g->total_workers; ++i)
+    {
+        __cilkrts_worker *w = g->workers[i];
+
+        // Close the log files, if we've opened them
+        if(w->l->record_replay_fptr)
+            fclose(w->l->record_replay_fptr);
+
+        if (w->l->replay_list_root)
+        {
+            // We should have consumed the entire list
+            CILK_ASSERT(ped_type_last == w->l->replay_list_entry->m_type);
+
+            replay_entry_t *entry = w->l->replay_list_root;
+            while (ped_type_last != entry->m_type)
+            {
+                // Free the pedigree memory for each entry
+                entry->unload();
+                entry++;
+            }
+            __cilkrts_free(w->l->replay_list_root);
+            w->l->replay_list_root = NULL;
+            w->l->replay_list_entry = NULL;
+        }
+    }
+}
+
+__CILKRTS_END_EXTERN_C
diff --git a/libcilkrts/runtime/record-replay.h b/libcilkrts/runtime/record-replay.h
new file mode 100644 (file)
index 0000000..c1c5a68
--- /dev/null
@@ -0,0 +1,432 @@
+/* record_replay.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2012-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+/**
+ * @file record-replay.h
+ *
+ * @brief record-replay.h and .cpp encapsulate most of the functionality to
+ * record and play back a Cilk Plus application.
+ *
+ * Recording is directed by the setting of the CILK_RECORD_LOG environment
+ * variable.  If it's defined, the value specifies the root we'll use to
+ * generate files for each worker using the following format string:
+ * "%s%d.cilklog", where the integer is the value of w->self.
+ *
+ * Replay is directed by the setting of the CILK_REPLAY_LOG environment
+ * variable, interpreted the same way as CILK_RECORD_LOG.  If both
+ * CILK_RECORD_LOG and CILK_REPLAY_LOG are defined, a warning will be given
+ * and the attempt to record a log will be ignored.
+ *
+ * Recording is relatively straightforward.  We write all information about a
+ * worker to a per-worker file.
+ *
+ * Each pedigree record consists of the following fields.  All fields must be
+ * present in every record to make parsing easy.
+ *    - Type - A string identifying the pedigree record.  See the PED_TYPE_STR_
+ *      macros for the currently defined values.
+ *    - Pedigree - A string of pedigree values, with underscores between
+ *      adjacent values.
+ *    - i1 - Record type-specific value.  -1 if not used.
+ *    - i2 - Record type-specific value.  -1 if not used.
+ *
+ * WORKERS record - only written to the file for worker 0.  Note that this is
+ * the first worker in the workers array. Worker 0 is the first system worker,
+ * *NOT* a user worker.
+ *  - Type: "Workers"
+ *  - Pedigree: Always "0" - ignored
+ *  - i1: Number of workers (g->P) when we recorded the log.  A mismatch when
+ *        we attempt to replay the log will result in aborting the execution.
+ *  - i2: Log version number - Specified by PED_VERSION in record-replay.cpp
+ *
+ * STEAL record - written after a successful steal.
+ *  - Type: "Steal"
+ *  - Pedigree: Pedigree of stolen frame
+ *  - i1: Worker the frame was stolen from
+ *  - i2: -1
+ *
+ * SYNC record - written after a worker continues from a sync.
+ *  - Type: "Sync"
+ *  - Pedigree: Pedigree of sync.  Note that this is the pedigree *before*
+ *        the pedigree in incremented in setup_for_execution_pedigree().
+ *  - i1: -1
+ *  - i2: -1
+ *
+ * ORPHANED record - saved on a return to a stolen parent.
+ *  - Type: "Orphaned"
+ *  - Pedigree: Pedigree of the parent frame *before* the pedigree is
+ *        incremented by the return
+ *  - i1: -1
+ *  - i2: -1
+ *
+ * On replay, the data is loaded into a per-worker array, and the data is
+ * consumed in order as needed.
+ */
+
+#ifndef INCLUDED_RECORD_REPLAY_DOT_H
+#define INCLUDED_RECORD_REPLAY_DOT_H
+
+#include "cilk/common.h"
+#include "global_state.h"
+
+/**
+ * Define CILK_RECORD_REPLAY to enable record/replay functionality.  If
+ * CILK_RECORD_REPLAY is not defined, all of the record/replay functions in
+ * record-replay.h will be stubbed out.  Since they're declared as inline,
+ * functions, the resulting build should have no performance impact due to
+ * the implementation or record/replay.
+ */
+ #define CILK_RECORD_REPLAY 1
+
+/**
+ * Define RECORD_ON_REPLAY=1 to write logs when we're replaying a log.  This
+ * should only be needed when debugging the replay functionality.  This should
+ * always be defined as 0 when record-replay.h is checked in.
+ */
+#define RECORD_ON_REPLAY 0
+
+__CILKRTS_BEGIN_EXTERN_C
+
+#ifdef CILK_RECORD_REPLAY
+// Declarations of internal record/replay functions.  The inlined versions
+// further down do some preliminary testing (like if we're not recording or
+// replaying) and will stub out the functionality if we've compiled out the
+// record/replay feature
+int replay_match_sync_pedigree_internal(__cilkrts_worker *w);
+void replay_wait_for_steal_if_parent_was_stolen_internal(__cilkrts_worker *w);
+void replay_record_steal_internal(__cilkrts_worker *w, int32_t victim_id);
+void replay_record_sync_internal(__cilkrts_worker *w);
+void replay_record_orphaned_internal(__cilkrts_worker *w);
+int replay_match_victim_pedigree_internal(__cilkrts_worker *w, __cilkrts_worker *victim);
+void replay_advance_from_sync_internal (__cilkrts_worker *w);
+int replay_get_next_recorded_victim_internal(__cilkrts_worker *w);
+#endif //  CILK_RECORD_REPLAY
+
+// Publically defined record/replay API
+
+/**
+ * If we're replaying a log, wait for our parent to be stolen if it was when
+ * the log was recorded.  If record/replay is compiled out, this is a noop.
+ *
+ * @param w The __cilkrts_worker we're executing on.  The worker's replay
+ * list will be checked for a ORPHANED record with a matching pedigree.  If
+ * there is a match, the ORPHANED record will be consumed.
+ */
+#ifdef CILK_RECORD_REPLAY
+__CILKRTS_INLINE
+void replay_wait_for_steal_if_parent_was_stolen(__cilkrts_worker *w)
+{
+    // Only check if we're replaying a log
+    if (REPLAY_LOG == w->g->record_or_replay)
+        replay_wait_for_steal_if_parent_was_stolen_internal(w);
+}
+#else
+__CILKRTS_INLINE
+void replay_wait_for_steal_if_parent_was_stolen(__cilkrts_worker *w)
+{
+    // If record/replay is disabled, we never wait
+}
+#endif //  CILK_RECORD_REPLAY
+
+/**
+ * Called from random_steal() to override the ID of the randomly chosen victim
+ * worker which this worker will attempt to steal from. Returns the worker id
+ * of the next victim this worker was recorded stealing from, or -1 if the
+ * next record in the log is not a STEAL.
+ *
+ * @note This call does NOT attempt to match the pedigree.  That will be done
+ * by replay_match_victim_pedigree() after random_steal() has locked the victim
+ * worker.
+ *
+ * @param w The __cilkrts_worker we're executing on.  The worker's replay log
+ * is checked for a STEAL record.  If we've got one, the stolen worker ID is
+ * returned.
+ * @param id The randomly chosen victim worker ID.  If we're not replaying a
+ * log, or if record/replay has been compiled out, this is the value that
+ * will be returned.
+ *
+ * @return id if we're not replaying a log
+ * @return -1 if the next record is not a STEAL
+ * @return recorded stolen worker ID if we've got a matching STEAL record
+ */
+#ifdef CILK_RECORD_REPLAY
+__CILKRTS_INLINE
+int replay_get_next_recorded_victim(__cilkrts_worker *w, int id)
+{
+    // Only check if we're replaying a log
+    if (REPLAY_LOG == w->g->record_or_replay)
+        return replay_get_next_recorded_victim_internal(w);
+    else
+        return id;
+}
+#else
+__CILKRTS_INLINE
+int replay_get_next_recorded_victim(__cilkrts_worker *w, int id)
+{
+    // Record/replay is disabled.  Always return the original worker id
+    return id;
+}
+#endif //  CILK_RECORD_REPLAY
+
+/**
+ * Initialize per-worker data for record/replay.  A noop if record/replay
+ * is disabled, or if we're not recording or replaying anything.
+ *
+ * If we're recording a log, this will ready us to create the per-worker
+ * logs.
+ *
+ * If we're replaying a log, this will read the logs into the per-worker
+ * structures.
+ *
+ * @param g Cilk runtime global state
+ */
+void replay_init_workers(global_state_t *g);
+
+/**
+ * Record a record on a successful steal.  A noop if record/replay is
+ * diabled, or if we're not recording anything
+ *
+ * @param w The __cilkrts_worker we're executing on.  The pedigree of
+ * the stolen frame will be walked to generate the STEAL record.
+ *
+ * @param victim_id The worker ID of the worker w stole from.
+ */
+#ifdef CILK_RECORD_REPLAY
+__CILKRTS_INLINE
+void replay_record_steal(__cilkrts_worker *w, int32_t victim_id)
+{
+#if RECORD_ON_REPLAY
+    // If we're recording on replay, write the record if we're recording or
+    // replaying
+    if (RECORD_REPLAY_NONE == w->g->record_or_replay)
+        return;
+#else
+    // Only write the record if we're recording
+    if (RECORD_LOG != w->g->record_or_replay)
+        return;
+#endif
+
+    replay_record_steal_internal(w, victim_id);
+}
+#else
+__CILKRTS_INLINE
+void replay_record_steal(__cilkrts_worker *w, int32_t victim_id)
+{
+}
+#endif //  CILK_RECORD_REPLAY
+
+/**
+ * Record a record when continuing after a sync.  A noop if record/replay is
+ * diabled, or if we're not recording anything, or if the sync was abandoned,
+ * meaning this isn't the worker that continues from the sync.
+ *
+ * @param w The __cilkrts_worker for we're executing on.  The pedigree of
+ * the sync-ing frame will be walked to generate the SYNC record.
+ *
+ * @param continuing True if this worker will be continuing from the
+ * cilk_sync.  A SYNC record will only be generated if continuing is true.
+ */
+#ifdef CILK_RECORD_REPLAY
+__CILKRTS_INLINE
+void replay_record_sync(__cilkrts_worker *w, int continuing)
+{
+    // If this was not the last worker to the syn, return
+    if (! continuing)
+        return;
+
+#if RECORD_ON_REPLAY
+    // If we're recording on replay, write the record if we're recording or
+    // replaying
+    if (RECORD_REPLAY_NONE == w->g->record_or_replay)
+        return;
+#else
+    // Only write the record if we're recording
+    if (RECORD_LOG != w->g->record_or_replay)
+        return;
+#endif
+
+    replay_record_sync_internal(w);
+}
+#else
+__CILKRTS_INLINE
+void replay_record_sync(__cilkrts_worker *w, int abandoned)
+{
+}
+#endif //  CILK_RECORD_REPLAY
+
+/**
+ * Record a record on a return to a stolen parent.  A noop if record/replay is
+ * diabled, or if we're not recording anything.
+ *
+ * @param w The __cilkrts_worker for we're executing on.  The pedigree of the
+ * frame that has discovered that its parent has been stolken will be walked
+ * to generate the ORPHANED record.
+ */
+#ifdef CILK_RECORD_REPLAY
+__CILKRTS_INLINE
+void replay_record_orphaned(__cilkrts_worker *w)
+{
+#if RECORD_ON_REPLAY
+    // If we're recording on replay, write the record if we're recording or
+    // replaying
+    if (RECORD_REPLAY_NONE == w->g->record_or_replay)
+        return;
+#else
+    // Only write the record if we're recording
+    if (RECORD_LOG != w->g->record_or_replay)
+        return;
+#endif
+
+    replay_record_orphaned_internal(w);
+}
+#else
+__CILKRTS_INLINE
+void replay_record_orphaned(__cilkrts_worker *w)
+{
+}
+#endif //  CILK_RECORD_REPLAY
+
+/**
+ * Test whether the frame at the head of the victim matches the pedigree of
+ * the frame that was recorded being stolen.  Called in random steal to verify
+ * that we're about to steal the correct frame.
+ *
+ * @param w The __cilkrts_worker for we're executing on.  The current worker
+ * is needed to find the replay entry to be checked.
+ *
+ * @param victim The __cilkrts_worker for we're proposing to steal a frame
+ * from.  The victim's head entry is 
+ * is needed to find the replay entry to be checked.
+ *
+ * @return 0 if we're replaying a log and the victim's pedigree does NOT match
+ * the next frame the worker is expected to steal.
+ *
+ * @return 1 in all other cases to indicate that the steal attempt should
+ * continue
+ */
+#ifdef CILK_RECORD_REPLAY
+__CILKRTS_INLINE
+int replay_match_victim_pedigree(__cilkrts_worker *w, __cilkrts_worker *victim)
+{
+    // We're not replaying a log. The victim is always acceptable
+    if (REPLAY_LOG != w->g->record_or_replay)
+        return 1;
+
+    // Return 1 if the victim's pedigree matches the frame the worker stole
+    // when we recorded the log
+    return replay_match_victim_pedigree_internal(w, victim);
+}
+#else
+__CILKRTS_INLINE
+int replay_match_victim_pedigree(__cilkrts_worker *w, __cilkrts_worker *victim)
+{
+    // Record/replay is disabled.  The victim is always acceptable
+    return 1;
+}
+#endif //  CILK_RECORD_REPLAY
+
+/**
+ * Test whether the current replay entry is a sync record matching the
+ * worker's pedigree.
+ *
+ * @param w The __cilkrts_worker for we're executing on.
+ *
+ * @return 1 if the current replay entry matches the current pedigree.
+ * @return 0 if there's no match, or if we're not replaying a log.
+ */
+#ifdef CILK_RECORD_REPLAY
+__CILKRTS_INLINE
+int replay_match_sync_pedigree(__cilkrts_worker *w)
+{
+    // If we're not replaying, assume no match
+    if (REPLAY_LOG != w->g->record_or_replay)
+        return 0;
+
+    return replay_match_sync_pedigree_internal(w);
+}
+#else
+__CILKRTS_INLINE
+int replay_match_sync_pedigree(__cilkrts_worker *w)
+{
+    // Record/replay is disabled.  Assume no match
+    return 0;
+}
+#endif
+
+/**
+ * Marks a sync record seen, advancing to the next record in the replay list.
+ *
+ * This function will only advance to the next record if:
+ *   - Record/replay hasn't been compiled out AND
+ *   - We're replaying a log AND
+ *   - A match was found AND
+ *   - The sync is not being abandoned
+ *
+ * @param w The __cilkrts_worker for we're executing on.
+ * @param match_found The value returned by replay_match_sync_pedigree().  If
+ * match_found is false, nothing is done.
+ * @param continuing  Flag indicating whether this worker will continue from
+ * the sync (it's the last worker to the sync) or if it will abandon the work
+ * and go to the scheduling loop to look for more work it can steal.
+ */
+#ifdef CILK_RECORD_REPLAY
+__CILKRTS_INLINE
+void replay_advance_from_sync(__cilkrts_worker *w, int match_found, int continuing)
+{
+    // If we're replaying a log, and the current sync wasn't abandoned, and we
+    // found a match in the log, mark the sync record seen.
+    if ((REPLAY_LOG == w->g->record_or_replay) && match_found && continuing)
+        replay_advance_from_sync_internal(w);
+}
+#else
+__CILKRTS_INLINE
+void replay_advance_from_sync(__cilkrts_worker *w, int match_found, int continuing)
+{
+}
+#endif
+
+/**
+ * Release any resources used to read or write a replay log.
+ *
+ * @param g Cilk runtime global state
+ */
+void replay_term(global_state_t *g);
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_RECORD_REPLAY_DOT_H)
diff --git a/libcilkrts/runtime/reducer_impl.cpp b/libcilkrts/runtime/reducer_impl.cpp
new file mode 100644 (file)
index 0000000..f20b9bc
--- /dev/null
@@ -0,0 +1,1012 @@
+/* reducer_impl.cpp                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  Patents Pending, Intel Corporation.
+ **************************************************************************/
+
+/**
+ * Support for reducers
+ */
+
+// ICL: Don't complain about conversion from pointer to same-sized integral type
+// in hashfun.  That's why we're using size_t
+#ifdef _WIN32
+#   pragma warning(disable: 1684)
+#endif
+
+#include "reducer_impl.h"
+#include "scheduler.h"
+#include "bug.h"
+#include "os.h"
+#include "global_state.h"
+#include "frame_malloc.h"
+
+#include "cilk/hyperobject_base.h"
+#include "cilktools/cilkscreen.h"
+#include "internal/abi.h"
+
+#if REDPAR_DEBUG > 0
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+
+#define DBG if(0) // if(1) enables some internal checks
+
+// Check that w is the currently executing worker.  This method is a
+// no-op unless the debug level is set high enough.
+static inline void verify_current_wkr(__cilkrts_worker *w)
+{
+#if REDPAR_DEBUG >= 5
+    __cilkrts_worker* tmp = __cilkrts_get_tls_worker();
+    if (w != tmp) {
+        fprintf(stderr, "W=%d, actual=%d... missing a refresh....\n",
+                w->self,
+                tmp->self);
+    }
+    CILK_ASSERT(w == tmp); // __cilkrts_get_tls_worker());
+#endif
+}
+
+// Suppress clang warning that the expression result is unused
+#if defined(__clang__) && (! defined(__INTEL_COMPILER))
+#   pragma clang diagnostic push
+#   pragma clang diagnostic ignored "-Wunused-value"
+#endif // __clang__
+
+/// Helper class to disable and re-enable Cilkscreen
+struct DisableCilkscreen
+{
+    DisableCilkscreen () { __cilkscreen_disable_checking(); }
+    ~DisableCilkscreen () { __cilkscreen_enable_checking(); }
+};
+
+/// Helper class to enable and re-disable Cilkscreen
+struct EnableCilkscreen
+{
+    EnableCilkscreen () { __cilkscreen_enable_checking(); }
+    ~EnableCilkscreen () { __cilkscreen_disable_checking(); }
+};
+
+#if defined(__clang__) && (! defined(__INTEL_COMPILER))
+#   pragma clang diagnostic pop
+#endif // __clang__
+
+/**
+ * @brief Element for a hyperobject
+ */
+struct elem {
+    void                       *key;  ///< Shared key for this hyperobject
+    __cilkrts_hyperobject_base *hb;   ///< Base of the hyperobject.
+    void                       *view; ///< Strand-private view of this hyperobject
+    /// Destroy and deallocate the view object for this element and set view to
+    /// null.
+    void destroy();
+
+    /// Returns true if this element contains a leftmost view.
+    bool is_leftmost() const;
+};
+
+/** Bucket containing at most NMAX elements */
+struct bucket {
+    /// Size of the array of elements for this bucket
+    size_t nmax;
+
+    /**
+     * We use the ``struct hack'' to allocate an array of variable
+     * dimension at the end of the struct.  However, we allocate a
+     * total of NMAX+1 elements instead of NMAX.  The last one always
+     * has key == 0, which we use as a termination criterion
+     */
+    elem el[1];
+};
+
+/**
+ * Class that implements the map for reducers so we can find the
+ * view for a strand.
+ */
+struct cilkred_map {
+    /** Handy pointer to the global state */
+    global_state_t *g;
+
+    /** Number of elements in table */
+    size_t nelem;
+
+    /** Number of buckets */
+    size_t nbuckets;
+
+    /** Array of pointers to buckets */
+    bucket **buckets;
+
+    /** Set true if merging (for debugging purposes) */
+    bool merging;
+
+    /** Set true for leftmost reducer map */
+    bool is_leftmost;
+
+    /** @brief Return element mapped to 'key' or null if not found. */
+    elem *lookup(void *key);
+
+    /**
+     * @brief Insert key/value element into hash map without rehashing.
+     * Does not check for duplicate key.
+     */
+    elem *insert_no_rehash(__cilkrts_worker           *w,
+                          void                       *key,
+                          __cilkrts_hyperobject_base *hb,
+                           void                       *value);
+
+    /**
+     * @brief Insert key/value element into hash map, rehashing if necessary.
+     * Does not check for duplicate key.
+     */
+    inline elem *rehash_and_insert(__cilkrts_worker           *w,
+                                  void                       *key,
+                                  __cilkrts_hyperobject_base *hb,
+                                   void                       *value);
+
+    /** @brief Grow bucket by one element, reallocating bucket if necessary */
+    static elem *grow(__cilkrts_worker *w, bucket **bp);
+
+    /** @brief Rehash a worker's reducer map */
+    void rehash(__cilkrts_worker *);
+
+    /**
+     * @brief Returns true if a rehash is needed due to the number of elements that
+     * have been inserted.
+     */
+    inline bool need_rehash_p() const;
+
+    /** @brief Allocate and initialize the buckets */
+    void make_buckets(__cilkrts_worker *w, size_t nbuckets);
+
+    /**
+     * Specify behavior when the same key is present in both maps passed
+     * into merge().
+     */
+    enum merge_kind
+    {
+        MERGE_UNORDERED, ///< Assertion fails
+        MERGE_INTO_LEFT, ///< Merges the argument from the right into the left
+        MERGE_INTO_RIGHT ///< Merges the argument from the left into the right
+    };
+
+    /**
+     * @brief Merge another reducer map into this one, destroying the other map in
+     * the process.
+     */
+    __cilkrts_worker* merge(__cilkrts_worker *current_wkr,
+                           cilkred_map      *other_map,
+                           enum merge_kind   kind);
+
+    /** @brief check consistency of a reducer map */
+    void check(bool allow_null_view);
+
+    /** @brief Test whether the cilkred_map is empty */
+    bool is_empty() { return nelem == 0; }
+};
+
+static inline struct cilkred_map* install_new_reducer_map(__cilkrts_worker *w) {
+    cilkred_map *h;
+    h = __cilkrts_make_reducer_map(w);
+    w->reducer_map = h;
+    return h;
+}
+
+static size_t sizeof_bucket(size_t nmax)
+{
+    bucket *b = 0;
+    return (sizeof(*b) + nmax * sizeof(b->el[0]));
+}
+
+static bucket *alloc_bucket(__cilkrts_worker *w, size_t nmax)
+{
+    bucket *b = (bucket *)
+        __cilkrts_frame_malloc(w, sizeof_bucket(nmax));
+    b->nmax = nmax;
+    return b;
+}
+
+static void free_bucket(__cilkrts_worker *w, bucket **bp)
+{
+    bucket *b = *bp;
+    if (b) {
+        __cilkrts_frame_free(w, b, sizeof_bucket(b->nmax));
+        *bp = 0;
+    }
+}
+
+/* round up nmax to fill a memory allocator block completely */
+static size_t roundup(size_t nmax)
+{
+    size_t sz = sizeof_bucket(nmax);
+
+    /* round up size to a full malloc block */
+    sz = __cilkrts_frame_malloc_roundup(sz);
+
+    /* invert sizeof_bucket() */
+    nmax = ((sz - sizeof(bucket)) / sizeof(elem));
+     
+    return nmax;
+}
+
+static bool is_power_of_2(size_t n)
+{
+    return (n & (n - 1)) == 0;
+}
+
+void cilkred_map::make_buckets(__cilkrts_worker *w, 
+                               size_t            new_nbuckets)
+{     
+    nbuckets = new_nbuckets;
+
+    CILK_ASSERT(is_power_of_2(nbuckets));
+#if defined __GNUC__ && defined __ICC 
+    /* bug workaround -- suppress calls to _intel_fast_memset */
+    bucket *volatile*new_buckets = (bucket *volatile*)
+#else
+    bucket **new_buckets = (bucket **)
+#endif
+        __cilkrts_frame_malloc(w, nbuckets * sizeof(*(buckets)));
+
+#if REDPAR_DEBUG >= 1
+    fprintf(stderr, "W=%d, desc=make_buckets, new_buckets=%p, new_nbuckets=%zd\n",
+           w->self, new_buckets, new_nbuckets);
+#endif
+
+    for (size_t i = 0; i < new_nbuckets; ++i)
+        new_buckets[i] = 0;
+#if defined __GNUC__ && defined __ICC 
+    buckets = (bucket **)new_buckets;
+#else
+    buckets = new_buckets;
+#endif
+    nelem = 0;
+}
+
+static void free_buckets(__cilkrts_worker  *w, 
+                         bucket           **buckets,
+                         size_t             nbuckets)
+{
+    size_t i;
+
+#if REDPAR_DEBUG >= 1
+    verify_current_wkr(w);
+    fprintf(stderr, "W=%d, desc=free_buckets, buckets=%p, size=%zd\n",
+           w->self, buckets,
+           nbuckets * sizeof(*buckets));
+#endif
+
+    for (i = 0; i < nbuckets; ++i)
+        free_bucket(w, buckets + i);
+
+    __cilkrts_frame_free(w, buckets, nbuckets * sizeof(*buckets));
+}
+
+static size_t minsz(size_t nelem)
+{
+    return 1U + nelem + nelem / 8U;
+}
+
+static size_t nextsz(size_t nelem)
+{
+    return 2 * nelem;
+}
+
+bool cilkred_map::need_rehash_p() const
+{
+    return minsz(nelem) > nbuckets;
+}
+
+static inline size_t hashfun(const cilkred_map *h, void *key)
+{
+    size_t k = (size_t) key;
+
+    k ^= k >> 21;
+    k ^= k >> 8;
+    k ^= k >> 3;
+
+    return k & (h->nbuckets - 1);
+}
+
+// Given a __cilkrts_hyperobject_base, return the key to that hyperobject in
+// the reducer map.
+static inline void* get_hyperobject_key(__cilkrts_hyperobject_base *hb)
+{
+    // The current implementation uses the address of the lefmost view as the
+    // key.
+    return reinterpret_cast<char*>(hb) + hb->__view_offset;
+}
+
+// Given a hyperobject key, return a pointer to the leftmost object.  In the
+// current implementation, the address of the leftmost object IS the key, so
+// this function is an effective noop.
+static inline void* get_leftmost_view(void *key)
+{
+    return key;
+}
+
+/* debugging support: check consistency of a reducer map */
+void cilkred_map::check(bool allow_null_view)
+{
+    size_t count = 0;
+
+    CILK_ASSERT(buckets);
+    for (size_t i = 0; i < nbuckets; ++i) {
+        bucket *b = buckets[i];
+        if (b) 
+            for (elem *el = b->el; el->key; ++el) {
+                CILK_ASSERT(allow_null_view || el->view);
+                ++count;
+            }
+    }
+    CILK_ASSERT(nelem == count);
+    /*global_reducer_map::check();*/
+}             
+
+/* grow bucket by one element, reallocating bucket if necessary */
+elem *cilkred_map::grow(__cilkrts_worker *w, 
+                        bucket          **bp)
+{
+    size_t i, nmax, nnmax;
+    bucket *b, *nb;
+
+    b = *bp;
+    if (b) {
+        nmax = b->nmax;
+        /* find empty element if any */
+        for (i = 0; i < nmax; ++i) 
+            if (b->el[i].key == 0) 
+                return &(b->el[i]);
+        /* do not use the last one even if empty */
+    } else {
+        nmax = 0;
+    }
+
+    verify_current_wkr(w);
+    /* allocate a new bucket */
+    nnmax = roundup(2 * nmax);
+    nb = alloc_bucket(w, nnmax);
+
+
+    /* copy old bucket into new */
+    for (i = 0; i < nmax; ++i)
+        nb->el[i] = b->el[i];
+     
+    free_bucket(w, bp); *bp = nb;
+
+    /* zero out extra elements */
+    for (; i < nnmax; ++i)
+        nb->el[i].key = 0;
+
+    /* zero out the last one */
+    nb->el[i].key = 0;
+  
+    return &(nb->el[nmax]);
+}
+
+elem *cilkred_map::insert_no_rehash(__cilkrts_worker           *w,
+                                   void                       *key,
+                                   __cilkrts_hyperobject_base *hb,
+                                    void                       *view)
+{
+
+#if REDPAR_DEBUG >= 2
+    fprintf(stderr, "[W=%d, desc=insert_no_rehash, this_map=%p]\n",
+           w->self, this);
+    verify_current_wkr(w);
+#endif
+    
+    CILK_ASSERT((w == 0 && g == 0) || w->g == g);
+    CILK_ASSERT(key != 0);
+    CILK_ASSERT(view != 0);
+           
+    elem *el = grow(w, &(buckets[hashfun(this, key)]));
+
+#if REDPAR_DEBUG >= 3
+    fprintf(stderr, "[W=%d, this=%p, inserting key=%p, view=%p, el = %p]\n",
+           w->self, this, key, view, el);
+#endif
+
+    el->key = key;
+    el->hb  = hb;
+    el->view = view;
+    ++nelem;
+
+    return el;
+}
+
+void cilkred_map::rehash(__cilkrts_worker *w)
+{
+#if REDPAR_DEBUG >= 1
+    fprintf(stderr, "[W=%d, desc=rehash, this_map=%p, g=%p, w->g=%p]\n",
+           w->self, this, g, w->g);
+    verify_current_wkr(w);
+#endif
+    CILK_ASSERT((w == 0 && g == 0) || w->g == g);
+    
+    size_t onbuckets = nbuckets;
+    size_t onelem = nelem;
+    bucket **obuckets = buckets;
+    size_t i;
+    bucket *b;
+
+    make_buckets(w, nextsz(nbuckets));
+     
+    for (i = 0; i < onbuckets; ++i) {
+        b = obuckets[i];
+        if (b) {
+            elem *oel;
+            for (oel = b->el; oel->key; ++oel)
+                insert_no_rehash(w, oel->key, oel->hb, oel->view);
+        }
+    }
+
+    CILK_ASSERT(nelem == onelem);
+
+    free_buckets(w, obuckets, onbuckets);
+}
+
+elem *cilkred_map::rehash_and_insert(__cilkrts_worker           *w,
+                                    void                       *key,
+                                     __cilkrts_hyperobject_base *hb,
+                                    void                       *view)
+{
+
+#if REDPAR_DEBUG >= 1
+    fprintf(stderr, "W=%d, this_map =%p, inserting key=%p, view=%p\n",
+           w->self, this, key, view);
+    verify_current_wkr(w);
+#endif
+
+    if (need_rehash_p()) 
+        rehash(w);
+
+    return insert_no_rehash(w, key, hb, view);
+}
+
+
+elem *cilkred_map::lookup(void *key)
+{
+    bucket *b = buckets[hashfun(this, key)];
+
+    if (b) {
+        elem *el;
+        for (el = b->el; el->key; ++el) {
+            if (el->key == key) {
+                CILK_ASSERT(el->view);
+                return el;
+            }
+        }
+    }
+
+    return 0;
+}
+
+void elem::destroy()
+{
+    if (! is_leftmost()) {
+
+        // Call destroy_fn and deallocate_fn on the view, but not if it's the
+        // leftmost view.
+        cilk_c_monoid *monoid = &(hb->__c_monoid);
+        cilk_c_reducer_destroy_fn_t    destroy_fn    = monoid->destroy_fn;
+        cilk_c_reducer_deallocate_fn_t deallocate_fn = monoid->deallocate_fn;
+       
+        destroy_fn((void*)hb, view);
+        deallocate_fn((void*)hb, view);
+    }
+
+    view = 0;
+}
+
+inline
+bool elem::is_leftmost() const
+{
+    // implementation uses the address of the leftmost view as the key, so if
+    // key == view, then this element refers to the leftmost view.
+    return key == view;
+}
+
+/* remove the reducer from the current reducer map.  If the reducer
+   exists in maps other than the current one, the behavior is
+   undefined. */
+extern "C"
+CILK_EXPORT void __CILKRTS_STRAND_STALE(
+    __cilkrts_hyper_destroy(__cilkrts_hyperobject_base *hb))
+{
+    // Disable Cilkscreen for the duration of this call.  The destructor for
+    // this class will re-enable Cilkscreen when the method returns.  This
+    // will prevent Cilkscreen from reporting apparent races in reducers
+    DisableCilkscreen x;
+
+    __cilkrts_worker* w = __cilkrts_get_tls_worker();
+    if (! w) {
+        // If no worker, then Cilk is not running and there is no reducer
+        // map.  Do nothing.  The reducer's destructor will take care of
+        // destroying the leftmost view.
+        return;
+    }
+
+const char *UNSYNCED_REDUCER_MSG =
+    "Destroying a reducer while it is visible to unsynced child tasks, or\n"
+    "calling CILK_C_UNREGISTER_REDUCER() on an unregistered reducer.\n"
+    "Did you forget a _Cilk_sync or CILK_C_REGISTER_REDUCER()?";
+
+    cilkred_map* h = w->reducer_map;
+    if (NULL == h)
+       cilkos_error(UNSYNCED_REDUCER_MSG); // Does not return
+
+    if (h->merging) {
+       verify_current_wkr(w);
+       __cilkrts_bug("User error: hyperobject used by another hyperobject");
+    }
+
+    void* key = get_hyperobject_key(hb);
+    elem *el = h->lookup(key);
+
+    // Verify that the reducer is being destroyed from the leftmost strand for
+    // which the reducer is defined.
+    if (! (el && el->is_leftmost()))
+       cilkos_error(UNSYNCED_REDUCER_MSG);
+
+#if REDPAR_DEBUG >= 3
+    fprintf(stderr, "[W=%d, key=%p, lookup in map %p, found el=%p, about to destroy]\n",
+            w->self, key, h, el);
+#endif
+       
+    // Remove the element from the hash bucket.  Do not bother shrinking
+    // the bucket. Note that the destroy() function does not actually
+    // call the destructor for the leftmost view.
+    el->destroy();
+    do {
+        el[0] = el[1];
+        ++el;
+    } while (el->key);
+    --h->nelem;
+
+#if REDPAR_DEBUG >= 2
+    fprintf(stderr, "[W=%d, desc=hyper_destroy_finish, key=%p, w->reducer_map=%p]\n",
+           w->self, key, w->reducer_map);
+#endif 
+}
+    
+extern "C"
+CILK_EXPORT
+void __cilkrts_hyper_create(__cilkrts_hyperobject_base *hb)
+{
+    // This function registers the specified hyperobject in the current
+    // reducer map and registers the initial value of the hyperobject as the
+    // leftmost view of the reducer.
+    __cilkrts_worker *w = __cilkrts_get_tls_worker();
+    if (! w) {
+        // If there is no worker, then there is nothing to do: The iniitial
+        // value will automatically be used as the left-most view when we
+        // enter Cilk.
+        return;
+    }
+
+    // Disable Cilkscreen for the duration of this call.  The destructor for
+    // this class will re-enable Cilkscreen when the method returns.  This
+    // will prevent Cilkscreen from reporting apparent races in reducers
+    DisableCilkscreen x;
+
+    void* key = get_hyperobject_key(hb);
+    void* view = get_leftmost_view(key);
+    cilkred_map *h = w->reducer_map;
+
+    if (__builtin_expect(!h, 0)) {
+       h = install_new_reducer_map(w);
+#if REDPAR_DEBUG >= 2
+       fprintf(stderr, "[W=%d, hb=%p, hyper_create, isntalled new map %p, view=%p]\n",
+               w->self, hb, h, view);
+#endif
+    }
+
+    /* Must not exist. */
+    CILK_ASSERT(h->lookup(key) == NULL);
+
+#if REDPAR_DEBUG >= 3
+    verify_current_wkr(w);
+    fprintf(stderr, "[W=%d, hb=%p, lookup in map %p of view %p, should be null]\n",
+           w->self, hb, h, view);
+    fprintf(stderr, "W=%d, h=%p, inserting key %p, view%p\n",
+           w->self,
+           h,
+           &(hb->__c_monoid),
+           view);
+#endif    
+
+    if (h->merging)
+        __cilkrts_bug("User error: hyperobject used by another hyperobject");
+
+    CILK_ASSERT(w->reducer_map == h);
+    // The address of the leftmost value is the same as the key for lookup.
+    (void) h->rehash_and_insert(w, view, hb, view);
+}
+
+extern "C"
+CILK_EXPORT void* __CILKRTS_STRAND_PURE(
+    __cilkrts_hyper_lookup(__cilkrts_hyperobject_base *hb))
+{
+    __cilkrts_worker* w = __cilkrts_get_tls_worker_fast();
+    void* key = get_hyperobject_key(hb);
+    if (! w)
+        return get_leftmost_view(key);
+
+    // Disable Cilkscreen for the duration of this call.  This will
+    // prevent Cilkscreen from reporting apparent races in reducers
+    DisableCilkscreen dguard;
+
+    if (__builtin_expect(w->g->force_reduce, 0))
+        __cilkrts_promote_own_deque(w);
+    cilkred_map* h = w->reducer_map;
+
+    if (__builtin_expect(!h, 0)) {
+       h = install_new_reducer_map(w);
+    }
+
+    if (h->merging)
+        __cilkrts_bug("User error: hyperobject used by another hyperobject");
+    elem* el = h->lookup(key);
+    if (! el) {
+        /* lookup failed; insert a new default element */
+        void *rep;
+
+        {
+            /* re-enable cilkscreen while calling the constructor */
+            EnableCilkscreen eguard;
+            if (h->is_leftmost)
+            {
+                // This special case is called only if the reducer was not
+                // registered using __cilkrts_hyper_create, e.g., if this is a
+                // C reducer in global scope or if there is no bound worker.
+                rep = get_leftmost_view(key);
+            }
+            else
+            {
+                rep = hb->__c_monoid.allocate_fn((void*)hb,
+                                                hb->__view_size);
+                // TBD: Handle exception on identity function
+                hb->__c_monoid.identity_fn((void*)hb, rep);
+            }
+        }
+
+#if REDPAR_DEBUG >= 3
+       fprintf(stderr, "W=%d, h=%p, inserting key %p, view%p\n",
+               w->self,
+               h,
+               &(hb->__c_monoid),
+               rep);
+       CILK_ASSERT(w->reducer_map == h);
+#endif
+        el = h->rehash_and_insert(w, key, hb, rep);
+    }
+
+    return el->view;
+}
+
+extern "C" CILK_EXPORT
+void* __cilkrts_hyperobject_alloc(void* ignore, std::size_t bytes)
+{
+    return std::malloc(bytes);
+}
+
+extern "C" CILK_EXPORT
+void __cilkrts_hyperobject_dealloc(void* ignore, void* view)
+{
+    std::free(view);
+}
+
+/* No-op destroy function */
+extern "C" CILK_EXPORT
+void __cilkrts_hyperobject_noop_destroy(void* ignore, void* ignore2)
+{
+}
+
+cilkred_map *__cilkrts_make_reducer_map(__cilkrts_worker *w)
+{
+    CILK_ASSERT(w);
+
+    cilkred_map *h;
+    size_t nbuckets = 1; /* default value */
+    
+    h = (cilkred_map *)__cilkrts_frame_malloc(w, sizeof(*h));
+#if REDPAR_DEBUG >= 1
+    fprintf(stderr, "[W=%d, desc=make_reducer_frame_malloc_reducer_map, h=%p]\n",
+           w->self, h);
+#endif
+
+    h->g = w ? w->g : 0;
+    h->make_buckets(w, nbuckets);
+    h->merging = false;
+    h->is_leftmost = false;
+
+    return h;
+}
+
+/* Destroy a reducer map.  The map must have been allocated
+   from the worker's global context and should have been
+   allocated from the same worker. */
+void __cilkrts_destroy_reducer_map(__cilkrts_worker *w, cilkred_map *h)
+{
+    CILK_ASSERT((w == 0 && h->g == 0) || w->g == h->g);
+    verify_current_wkr(w);
+
+    /* the reducer map is allowed to contain el->view == NULL here (and
+       only here).  We set el->view == NULL only when we know that the
+       map will be destroyed immediately afterwards. */
+    DBG h->check(/*allow_null_view=*/true);
+
+    bucket *b;
+    size_t i;
+
+    for (i = 0; i < h->nbuckets; ++i) {
+        b = h->buckets[i];
+        if (b) {
+            elem *el;
+            for (el = b->el; el->key; ++el) {
+                if (el->view)
+                    el->destroy();
+            }
+        }
+    }
+
+    free_buckets(w, h->buckets, h->nbuckets);
+
+#if REDPAR_DEBUG >= 1
+    fprintf(stderr, "W=%d, destroy_red_map, freeing map h=%p, size=%zd\n",
+           w->self, h, sizeof(*h));
+#endif
+    
+    __cilkrts_frame_free(w, h, sizeof(*h));
+}
+
+/* Set the specified reducer map as the leftmost map if is_leftmost is true,
+   otherwise, set it to not be the leftmost map. */
+void __cilkrts_set_leftmost_reducer_map(cilkred_map *h, int is_leftmost)
+{
+    h->is_leftmost = is_leftmost;
+}
+
+
+__cilkrts_worker* cilkred_map::merge(__cilkrts_worker *w,
+                                    cilkred_map *other_map,
+                                    enum merge_kind kind)
+{
+    // Disable Cilkscreen while the we merge the maps.  The destructor for
+    // the guard class will re-enable Cilkscreen when it goes out of scope.
+    // This will prevent Cilkscreen from reporting apparent races in between
+    // the reduce function and the reducer operations.  The Cilk runtime
+    // guarantees that a pair of reducer maps will only be merged when no 
+    // other strand will access them.
+    DisableCilkscreen guard;
+
+#if REDPAR_DEBUG >= 2
+    fprintf(stderr, "[W=%d, desc=merge, this_map=%p, other_map=%p]\n",
+           w->self,
+           this, other_map);
+#endif
+    // Remember the current stack frame.
+    __cilkrts_stack_frame *current_sf = w->current_stack_frame;
+    merging = true;
+    other_map->merging = true;
+
+    // Merging to the leftmost view is a special case because every leftmost
+    // element must be initialized before the merge.
+    CILK_ASSERT(!other_map->is_leftmost /* || kind == MERGE_UNORDERED */);
+    bool merge_to_leftmost = (this->is_leftmost
+                              /* && !other_map->is_leftmost */);
+
+    DBG check(/*allow_null_view=*/false);
+    DBG other_map->check(/*allow_null_view=*/false);
+
+    for (size_t i = 0; i < other_map->nbuckets; ++i) {
+        bucket *b = other_map->buckets[i];
+        if (b) {
+            for (elem *other_el = b->el; other_el->key; ++other_el) {
+                /* Steal the value from the other map, which will be
+                   destroyed at the end of this operation. */
+                void *other_view = other_el->view;
+                CILK_ASSERT(other_view);
+
+                void *key = other_el->key;
+               __cilkrts_hyperobject_base *hb = other_el->hb;
+                elem *this_el = lookup(key);
+
+                if (this_el == 0 && merge_to_leftmost) {
+                    /* Initialize leftmost view before merging. */
+                    void* leftmost = get_leftmost_view(key);
+                    // leftmost == other_view can be true if the initial view
+                    // was created in other than the leftmost strand of the
+                    // spawn tree, but then made visible to subsequent strands
+                    // (E.g., the reducer was allocated on the heap and the
+                    // pointer was returned to the caller.)  In such cases,
+                    // parallel semantics says that syncing with earlier
+                    // strands will always result in 'this_el' being null,
+                    // thus propagating the initial view up the spawn tree
+                    // until it reaches the leftmost strand.  When synching
+                    // with the leftmost strand, leftmost == other_view will be
+                    // true and we must avoid reducing the initial view with
+                    // itself.
+                    if (leftmost != other_view)
+                        this_el = rehash_and_insert(w, key, hb, leftmost);
+                }
+
+                if (this_el == 0) {
+                    /* move object from other map into this one */
+                    rehash_and_insert(w, key, hb, other_view);
+                    other_el->view = 0;
+                    continue; /* No element-level merge necessary */
+                }
+
+                /* The same key is present in both maps with values
+                   A and B.  Three choices: fail, A OP B, B OP A. */
+                switch (kind)
+                {
+                case MERGE_UNORDERED:
+                    __cilkrts_bug("TLS Reducer race");
+                    break;
+                case MERGE_INTO_RIGHT:
+                    /* Swap elements in order to preserve object
+                       identity */
+                    other_el->view = this_el->view;
+                    this_el->view = other_view;
+                    /* FALL THROUGH */
+                case MERGE_INTO_LEFT: {
+                    /* Stealing should be disabled during reduce
+                       (even if force-reduce is enabled). */
+
+#if DISABLE_PARALLEL_REDUCERS
+                   __cilkrts_stack_frame * volatile *saved_protected_tail;
+                   saved_protected_tail = __cilkrts_disallow_stealing(w, NULL);
+#endif
+
+                   {                   
+                       CILK_ASSERT(current_sf->worker == w);
+                       CILK_ASSERT(w->current_stack_frame == current_sf);
+
+                       /* TBD: if reduce throws an exception we need to stop it
+                          here. */
+                       hb->__c_monoid.reduce_fn((void*)hb,
+                                                this_el->view,
+                                                other_el->view);
+                       w = current_sf->worker;
+
+#if REDPAR_DEBUG >= 2
+                       verify_current_wkr(w);
+                       CILK_ASSERT(w->current_stack_frame == current_sf);
+#endif
+                   }
+
+#if DISABLE_PARALLEL_REDUCERS
+                   /* Restore stealing */
+                   __cilkrts_restore_stealing(w, saved_protected_tail);
+#endif
+
+                  } break;
+                }
+            }
+        }
+    }
+    this->is_leftmost = this->is_leftmost || other_map->is_leftmost;
+    merging = false;
+    other_map->merging = false;
+    verify_current_wkr(w);
+    __cilkrts_destroy_reducer_map(w, other_map);
+    return w;
+}
+
+
+/**
+ * Print routine for debugging the merging of reducer maps.
+ * A no-op unless REDPAR_DEBUG set high enough.
+ */
+static inline
+void debug_map_merge(__cilkrts_worker *w,
+                    cilkred_map      *left_map,
+                    cilkred_map      *right_map,
+                    __cilkrts_worker **final_wkr)
+{    
+#if REDPAR_DEBUG >= 2
+    fprintf(stderr, "[W=%d, desc=finish_merge, left_map=%p, right_map=%p, w->reducer_map=%p, right_ans=%p, final_wkr=%d]\n",
+           w->self, left_map, right_map, w->reducer_map, right_map, (*final_wkr)->self);
+#endif
+}
+
+
+/**
+ * merge RIGHT into LEFT;
+ * return whichever map allows for faster merge, and destroy the other one.
+ * 
+ * *w_ptr should be the currently executing worker.
+ * *w_ptr may change during execution if the reduction is parallel.
+ */ 
+cilkred_map*
+merge_reducer_maps(__cilkrts_worker **w_ptr,
+                  cilkred_map *left_map,
+                  cilkred_map *right_map)
+{
+    __cilkrts_worker *w = *w_ptr;
+    if (!left_map) {
+       debug_map_merge(w, left_map, right_map, w_ptr);
+        return right_map;
+    }
+
+    if (!right_map) {
+       debug_map_merge(w, left_map, right_map, w_ptr);
+        return left_map;
+    }
+    
+    /* Special case, if left_map is leftmost, then always merge into it.
+       For C reducers this forces lazy creation of the leftmost views. */
+    if (left_map->is_leftmost || left_map->nelem > right_map->nelem) { 
+       *w_ptr = left_map->merge(w, right_map, cilkred_map::MERGE_INTO_LEFT);
+       debug_map_merge(*w_ptr, left_map, right_map, w_ptr);
+        return left_map;
+    } else {
+        *w_ptr = right_map->merge(w, left_map, cilkred_map::MERGE_INTO_RIGHT);
+       debug_map_merge(*w_ptr, left_map, right_map, w_ptr);
+        return right_map;
+    }
+}
+
+/**
+ * Merges RIGHT into LEFT, and then repeatedly calls
+ * merge_reducer_maps_helper() until (*w_ptr)->reducer_map is NULL.
+ *
+ *  *w_ptr may change as reductions execute.
+ */ 
+cilkred_map*
+repeated_merge_reducer_maps(__cilkrts_worker **w_ptr,
+                           cilkred_map      *left_map,
+                           cilkred_map      *right_map)
+{
+    // Note: if right_map == NULL but w->reducer_map != NULL, then
+    // this loop will reduce w->reducer_map into left_map.
+    do {
+       left_map = merge_reducer_maps(w_ptr, left_map, right_map);
+       verify_current_wkr(*w_ptr);
+
+       // Pull any newly created reducer map and loop around again.
+       right_map = (*w_ptr)->reducer_map;
+       (*w_ptr)->reducer_map = NULL;
+    } while (right_map);
+    return left_map;
+}
+
+/* End reducer_impl.cpp */
diff --git a/libcilkrts/runtime/reducer_impl.h b/libcilkrts/runtime/reducer_impl.h
new file mode 100644 (file)
index 0000000..3425967
--- /dev/null
@@ -0,0 +1,128 @@
+/* reducer_impl.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file reducer_impl.h
+ *
+ * @brief Functions to implement reducers in the runtime.
+ */
+
+#ifndef INCLUDED_REDUCER_IMPL_DOT_H
+#define INCLUDED_REDUCER_IMPL_DOT_H
+
+#include <cilk/common.h>
+#include <internal/abi.h>
+#include "rts-common.h"
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * Construct an empty reducer map from the memory pool associated with the
+ * given worker.  This reducer map must be destroyed before the worker's
+ * associated global context is destroyed.
+ *
+ * @param w __cilkrts_worker the cilkred_map is being created for.
+ *
+ * @return Pointer to the initialized cilkred_map.
+ */
+COMMON_SYSDEP
+cilkred_map *__cilkrts_make_reducer_map(__cilkrts_worker *w);
+
+/**
+ * Destroy a reducer map.  The map must have been allocated from the worker's
+ * global context and should have been allocated from the same worker.
+ *
+ * @param w __cilkrts_worker the cilkred_map was created for.
+ * @param h The cilkred_map to be deallocated.
+ */
+COMMON_SYSDEP
+void __cilkrts_destroy_reducer_map(__cilkrts_worker *w,
+                                   cilkred_map *h);
+
+/**
+ * Set the specified reducer map as the leftmost map if is_leftmost is true,
+ * otherwise, set it to not be the leftmost map.
+ *
+ * @param h The cilkred_map to be modified.
+ * @param is_leftmost true if the reducer map is leftmost.
+ */
+COMMON_SYSDEP
+void __cilkrts_set_leftmost_reducer_map(cilkred_map *h,
+                                        int is_leftmost);
+
+/**
+ * Merge reducer map RIGHT_MAP into LEFT_MAP and return the result of the
+ * merge.  Both maps must be allocated from the global context associated
+ * with the specified worker.  The returned reducer map must be destroyed
+ * before the worker's associated global context is destroyed.
+ *
+ * If two cilkred_maps are specified, one will be destroyed and the other
+ * one will be returned as the merged cilkred_map.
+ *
+ * When reducers can contain nested parallelism, execution can return
+ * on a different worker than when it started (but still using the
+ * same stack).
+ *
+ * Upon return, *w_ptr stores the pointer to the worker that execution
+ * returns on.
+ *
+ * @param w_ptr      Pointer to the currently executing worker.
+ * @param left_map   The left cilkred_map.
+ * @param right_map  The right cilkred_map.
+ *                  
+ * @return pointer to merged cilkred_map.
+ */
+extern
+cilkred_map *merge_reducer_maps(__cilkrts_worker **w_ptr,
+                               cilkred_map *left_map,
+                               cilkred_map *right_map);
+
+/**
+ * Similar to merge_reducer_maps(), except that after merging
+ * RIGHT_MAP into LEFT_MAP, it repeatedly merges (*w_ptr)->reducer_map
+ * into LEFT_MAP.  This procedure ensures that any new reducers
+ * created by the reductions themselves also get merged into LEFT_MAP.
+ */ 
+extern
+cilkred_map *repeated_merge_reducer_maps(__cilkrts_worker **w_ptr,
+                                        cilkred_map *left_map,
+                                        cilkred_map *right_map);
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_REDUCER_IMPL_DOT_H)
diff --git a/libcilkrts/runtime/rts-common.h b/libcilkrts/runtime/rts-common.h
new file mode 100644 (file)
index 0000000..4ffde7c
--- /dev/null
@@ -0,0 +1,132 @@
+/* rts-common.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#ifndef INCLUDED_RTS_COMMON_DOT_H
+#define INCLUDED_RTS_COMMON_DOT_H
+
+/* Abbreviations API functions returning different types.  By using these
+ * abbreviations instead of using CILK_API(ret) directly, etags and other
+ * tools can more easily recognize function signatures.
+ */
+#define CILK_API_VOID          CILK_API(void)
+#define CILK_API_VOID_PTR      CILK_API(void*)
+#define CILK_API_INT           CILK_API(int)
+#define CILK_API_SIZET         CILK_API(size_t)
+#define CILK_API_TBB_RETCODE   CILK_API(__cilk_tbb_retcode)
+#define CILK_API_PEDIGREE      CILK_API(__cilkrts_pedigree) 
+
+/* Abbreviations ABI functions returning different types.  By using these
+ * abbreviations instead of using CILK_ABI(ret) directly, etags and other
+ * tools can more easily recognize function signatures.
+ */
+#define CILK_ABI_VOID        CILK_ABI(void)
+#define CILK_ABI_WORKER_PTR  CILK_ABI(__cilkrts_worker_ptr)
+#define CILK_ABI_THROWS_VOID CILK_ABI_THROWS(void)
+
+/* documentation aid to identify portable vs. nonportable
+   parts of the runtime.  See README for definitions. */
+#define COMMON_PORTABLE
+#define COMMON_SYSDEP
+#define NON_COMMON
+
+#if !(defined __GNUC__ || defined __ICC)
+#   define __builtin_expect(a_, b_) a_
+#endif
+
+#ifdef __cplusplus
+#   define cilk_nothrow throw()
+#else
+#   define cilk_nothrow /*empty in C*/
+#endif
+
+#ifdef __GNUC__
+#   define NORETURN void __attribute__((noreturn))
+#else
+#   define NORETURN void __declspec(noreturn)
+#endif
+
+#ifdef __GNUC__
+#   define NOINLINE __attribute__((noinline))
+#else
+#   define NOINLINE __declspec(noinline)
+#endif
+
+#ifndef __GNUC__
+#   define __attribute__(X)
+#endif
+
+/* Microsoft CL accepts "inline" for C++, but not for C.  It accepts 
+ * __inline for both.  Intel ICL accepts inline for C of /Qstd=c99
+ * is set.  The Cilk runtime is assumed to be compiled with /Qstd=c99
+ */
+#if defined(_MSC_VER) && ! defined(__INTEL_COMPILER)
+#   error define inline
+#   define inline __inline
+#endif
+
+/* Compilers that build the Cilk runtime are assumed to know about zero-cost
+ * intrinsics (__notify_intrinsic()).  For those that don't, #undef the
+ * following definition:
+ */
+//#define ENABLE_NOTIFY_ZC_INTRINSIC 1
+
+#if defined(__INTEL_COMPILER)
+/* The notify intrinsic was introduced in ICC 12.0. */
+#   if __INTEL_COMPILER <= 1200
+#       undef ENABLE_NOTIFY_ZC_INTRINSIC
+#   endif
+#elif defined(__VXWORKS__)
+#   undef ENABLE_NOTIFY_ZC_INTRINSIC
+#elif defined(__clang__)
+#   if !defined(__has_extension) || !__has_extension(notify_zc_intrinsic)
+#      undef ENABLE_NOTIFY_ZC_INTRINSIC
+#   endif
+#elif defined(__arm__)
+// __notify_zc_intrinsic not yet supported by gcc for ARM
+#   undef ENABLE_NOTIFY_ZC_INTRINSIC
+#endif
+
+// If ENABLE_NOTIFY_ZC_INTRINSIC is defined, use __notify_zc_intrisic
+#ifdef ENABLE_NOTIFY_ZC_INTRINSIC
+#   define NOTIFY_ZC_INTRINSIC(annotation, data) \
+    __notify_zc_intrinsic(annotation, data)
+#else
+#   define NOTIFY_ZC_INTRINSIC(annotation, data)
+#endif
+
+#endif // ! defined(INCLUDED_RTS_COMMON_DOT_H)
diff --git a/libcilkrts/runtime/scheduler.c b/libcilkrts/runtime/scheduler.c
new file mode 100644 (file)
index 0000000..bab6430
--- /dev/null
@@ -0,0 +1,3940 @@
+/* scheduler.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2007-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+/*
+ * Cilk scheduler
+ */
+
+#include "scheduler.h"
+#include "bug.h"
+#include "os.h"
+#include "os_mutex.h"
+#include "local_state.h"
+#include "signal_node.h"
+#include "full_frame.h"
+#include "sysdep.h"
+#include "except.h"
+#include "cilk_malloc.h"
+#include "pedigrees.h"
+#include "record-replay.h"
+
+#include <limits.h>
+#include <string.h> /* memcpy */
+#include <stdio.h>  // sprintf
+#include <stdlib.h> // malloc, free, abort
+
+#ifdef _WIN32
+#   pragma warning(disable:1786)   // disable warning: sprintf is deprecated
+#   include "sysdep-win.h"
+#   include "except-win32.h"
+#endif  // _WIN32
+
+// ICL: Don't complain about conversion from pointer to same-sized integral
+// type in __cilkrts_put_stack.  That's why we're using ptrdiff_t
+#ifdef _WIN32
+#   pragma warning(disable: 1684)
+#endif
+
+#include "cilk/cilk_api.h"
+#include "frame_malloc.h"
+#include "metacall_impl.h"
+#include "reducer_impl.h"
+#include "cilk-tbb-interop.h"
+#include "cilk-ittnotify.h"
+#include "stats.h"
+
+// ICL: Don't complain about loss of precision in myrand
+// I tried restoring the warning after the function, but it didn't
+// suppress it
+#ifdef _WIN32
+#   pragma warning(disable: 2259)
+#endif
+
+#ifndef _WIN32
+#   include <unistd.h>
+#endif
+
+#ifdef __VXWORKS__
+// redeclare longjmp() with noreturn to stop warnings
+extern __attribute__((noreturn)) 
+               void longjmp(jmp_buf, int);
+#endif
+
+//#define DEBUG_LOCKS 1
+#ifdef DEBUG_LOCKS
+// The currently executing worker must own this worker's lock
+#   define ASSERT_WORKER_LOCK_OWNED(w) \
+        { \
+            __cilkrts_worker *tls_worker = __cilkrts_get_tls_worker(); \
+            CILK_ASSERT((w)->l->lock.owner == tls_worker); \
+        }
+#else
+#   define ASSERT_WORKER_LOCK_OWNED(w)
+#endif // DEBUG_LOCKS
+
+// Options for the scheduler.
+enum schedule_t { SCHEDULE_RUN,
+                  SCHEDULE_WAIT,
+                  SCHEDULE_EXIT };
+
+// Return values for provably_good_steal()
+enum provably_good_steal_t
+{
+    ABANDON_EXECUTION,  // Not the last child to the sync - attempt to steal work
+    CONTINUE_EXECUTION, // Last child to the sync - continue executing on this worker
+    WAIT_FOR_CONTINUE   // The replay log indicates that this was the worker
+                        // which continued.  Loop until we are the last worker
+                        // to the sync.
+};
+
+
+// Verify that "w" is the worker we are currently executing on.
+// Because this check is expensive, this method is usually a no-op.
+static inline void verify_current_wkr(__cilkrts_worker *w)
+{
+#if ((REDPAR_DEBUG >= 3) || (FIBER_DEBUG >= 1))
+    // Lookup the worker from TLS and compare to w. 
+    __cilkrts_worker* tmp = __cilkrts_get_tls_worker();
+    if (w != tmp) {
+        fprintf(stderr, "Error.  W=%d, actual worker =%d...\n",
+                w->self,
+                tmp->self);
+    }
+    CILK_ASSERT(w == tmp);
+#endif
+}                                                            
+
+static enum schedule_t worker_runnable(__cilkrts_worker *w);
+
+// Scheduling-fiber functions:
+static void do_return_from_spawn (__cilkrts_worker *w,
+                                  full_frame *ff,
+                                  __cilkrts_stack_frame *sf);
+static void do_sync (__cilkrts_worker *w,
+                     full_frame *ff,
+                     __cilkrts_stack_frame *sf);
+
+// max is defined on Windows and VxWorks
+#if (! defined(_WIN32)) && (! defined(__VXWORKS__))
+    // TBD: definition of max() for Linux.
+#   define max(a, b) ((a) < (b) ? (b) : (a))
+#endif
+
+void __cilkrts_dump_stats_to_stderr(global_state_t *g)
+{
+#ifdef CILK_PROFILE
+    int i;
+    for (i = 0; i < g->total_workers; ++i) {
+        // Print out statistics for each worker.  We collected them,
+        // so why not print them out?
+        fprintf(stderr, "Stats for worker %d\n", i);
+        dump_stats_to_file(stderr, g->workers[i]->l->stats);
+        __cilkrts_accum_stats(&g->stats, g->workers[i]->l->stats);
+    }
+
+    // Also print out aggregate statistics.
+    dump_stats_to_file(stderr, &g->stats);
+#endif
+    fprintf(stderr,
+            "CILK PLUS Thread Info: P=%d, Q=%d\n",
+            g->P,
+            g->Q);
+    fprintf(stderr,
+            "CILK PLUS RUNTIME MEMORY USAGE: %lld bytes",
+            (long long)g->frame_malloc.allocated_from_os);
+#ifdef CILK_PROFILE
+    if (g->stats.stack_hwm)
+        fprintf(stderr, ", %ld stacks", g->stats.stack_hwm);
+#endif
+    fputc('\n', stderr);
+}
+
+static void validate_worker(__cilkrts_worker *w)
+{
+    /* check the magic numbers, for debugging purposes */
+    if (w->l->worker_magic_0 != WORKER_MAGIC_0 ||
+        w->l->worker_magic_1 != WORKER_MAGIC_1)
+        abort_because_rts_is_corrupted();
+}
+
+static void double_link(full_frame *left_ff, full_frame *right_ff)
+{
+    if (left_ff)
+        left_ff->right_sibling = right_ff;
+    if (right_ff)
+        right_ff->left_sibling = left_ff;
+}
+
+/* add CHILD to the right of all children of PARENT */
+static void push_child(full_frame *parent_ff, full_frame *child_ff)
+{
+    double_link(parent_ff->rightmost_child, child_ff);
+    double_link(child_ff, 0);
+    parent_ff->rightmost_child = child_ff;
+}
+
+/* unlink CHILD from the list of all children of PARENT */
+static void unlink_child(full_frame *parent_ff, full_frame *child_ff)
+{
+    double_link(child_ff->left_sibling, child_ff->right_sibling);
+
+    if (!child_ff->right_sibling) {
+        /* this is the rightmost child -- update parent link */
+        CILK_ASSERT(parent_ff->rightmost_child == child_ff);
+        parent_ff->rightmost_child = child_ff->left_sibling;
+    }
+    child_ff->left_sibling = child_ff->right_sibling = 0; /* paranoia */
+}
+
+static void incjoin(full_frame *ff)
+{
+    ++ff->join_counter;
+}
+
+static int decjoin(full_frame *ff)
+{
+    CILK_ASSERT(ff->join_counter > 0);
+    return (--ff->join_counter);
+}
+
+static int simulate_decjoin(full_frame *ff)
+{
+  CILK_ASSERT(ff->join_counter > 0);
+  return (ff->join_counter - 1);
+}
+
+/*
+ * Pseudo-random generator defined by the congruence S' = 69070 * S
+ * mod (2^32 - 5).  Marsaglia (CACM July 1993) says on page 107 that
+ * this is a ``good one''.  There you go.
+ *
+ * The literature makes a big fuss about avoiding the division, but
+ * for us it is not worth the hassle.
+ */
+static const unsigned RNGMOD = ((1ULL << 32) - 5);
+static const unsigned RNGMUL = 69070U;
+
+static unsigned myrand(__cilkrts_worker *w)
+{
+    unsigned state = w->l->rand_seed;
+    state = (unsigned)((RNGMUL * (unsigned long long)state) % RNGMOD);
+    w->l->rand_seed = state;
+    return state;
+}
+
+static void mysrand(__cilkrts_worker *w, unsigned seed)
+{
+    seed %= RNGMOD;
+    seed += (seed == 0); /* 0 does not belong to the multiplicative
+                            group.  Use 1 instead */
+    w->l->rand_seed = seed;
+}
+
+/* W grabs its own lock */
+void __cilkrts_worker_lock(__cilkrts_worker *w)
+{
+    validate_worker(w);
+    CILK_ASSERT(w->l->do_not_steal == 0);
+
+    /* tell thieves to stay out of the way */
+    w->l->do_not_steal = 1;
+    __cilkrts_fence(); /* probably redundant */
+
+    __cilkrts_mutex_lock(w, &w->l->lock);
+}
+
+void __cilkrts_worker_unlock(__cilkrts_worker *w)
+{
+    __cilkrts_mutex_unlock(w, &w->l->lock);
+    CILK_ASSERT(w->l->do_not_steal == 1);
+    /* The fence is probably redundant.  Use a release
+       operation when supported (gcc and compatibile);
+       that is faster on x86 which serializes normal stores. */
+#if defined __GNUC__ && (__GNUC__ * 10 + __GNUC_MINOR__ > 43 || __ICC >= 1110)
+    __sync_lock_release(&w->l->do_not_steal);
+#else
+    w->l->do_not_steal = 0;
+    __cilkrts_fence(); /* store-store barrier, redundant on x86 */
+#endif
+}
+
+/* try to acquire the lock of some *other* worker */
+static int worker_trylock_other(__cilkrts_worker *w,
+                                __cilkrts_worker *other)
+{
+    int status = 0;
+
+    validate_worker(other);
+
+    /* This protocol guarantees that, after setting the DO_NOT_STEAL
+       flag, worker W can enter its critical section after waiting for
+       the thief currently in the critical section (if any) and at
+       most one other thief.  
+
+       This requirement is overly paranoid, but it should protect us
+       against future nonsense from OS implementors.
+    */
+
+    /* compete for the right to disturb OTHER */
+    if (__cilkrts_mutex_trylock(w, &other->l->steal_lock)) {
+        if (other->l->do_not_steal) {
+            /* leave it alone */
+        } else {
+            status = __cilkrts_mutex_trylock(w, &other->l->lock);
+        }
+        __cilkrts_mutex_unlock(w, &other->l->steal_lock);
+    }
+
+
+    return status;
+}
+
+static void worker_unlock_other(__cilkrts_worker *w,
+                                __cilkrts_worker *other)
+{
+    __cilkrts_mutex_unlock(w, &other->l->lock);
+}
+
+
+/* Lock macro Usage:
+    BEGIN_WITH_WORKER_LOCK(w) {
+        statement;
+        statement;
+        BEGIN_WITH_FRAME_LOCK(w, ff) {
+            statement;
+            statement;
+        } END_WITH_FRAME_LOCK(w, ff);
+    } END_WITH_WORKER_LOCK(w);
+ */
+#define BEGIN_WITH_WORKER_LOCK(w) __cilkrts_worker_lock(w); do
+#define END_WITH_WORKER_LOCK(w)   while (__cilkrts_worker_unlock(w), 0)
+
+// TBD(jsukha): These are worker lock acquistions on
+// a worker whose deque is empty.  My conjecture is that we
+// do not need to hold the worker lock at these points.
+// I have left them in for now, however.
+//
+// #define REMOVE_POSSIBLY_OPTIONAL_LOCKS
+#ifdef REMOVE_POSSIBLY_OPTIONAL_LOCKS
+    #define BEGIN_WITH_WORKER_LOCK_OPTIONAL(w) do
+    #define END_WITH_WORKER_LOCK_OPTIONAL(w)   while (0)
+#else
+    #define BEGIN_WITH_WORKER_LOCK_OPTIONAL(w) __cilkrts_worker_lock(w); do
+    #define END_WITH_WORKER_LOCK_OPTIONAL(w)   while (__cilkrts_worker_unlock(w), 0)
+#endif
+
+
+#define BEGIN_WITH_FRAME_LOCK(w, ff)                                     \
+    do { full_frame *_locked_ff = ff; __cilkrts_frame_lock(w, _locked_ff); do
+
+#define END_WITH_FRAME_LOCK(w, ff)                       \
+    while (__cilkrts_frame_unlock(w, _locked_ff), 0); } while (0)
+
+/* W becomes the owner of F and F can be stolen from W */
+static void make_runnable(__cilkrts_worker *w, full_frame *ff)
+{
+    w->l->frame_ff = ff;
+
+    /* CALL_STACK is invalid (the information is stored implicitly in W) */
+    ff->call_stack = 0;
+}
+
+/*
+ * The worker parameter is unused, except for print-debugging purposes.
+ */
+static void make_unrunnable(__cilkrts_worker *w,
+                            full_frame *ff,
+                            __cilkrts_stack_frame *sf,
+                            int is_loot,
+                            const char *why)
+{
+    /* CALL_STACK becomes valid again */
+    ff->call_stack = sf;
+
+    if (sf) {
+#if CILK_LIB_DEBUG
+        if (__builtin_expect(sf->flags & CILK_FRAME_EXITING, 0))
+            __cilkrts_bug("W%d suspending exiting frame %p/%p\n", w->self, ff, sf);
+#endif
+        sf->flags |= CILK_FRAME_STOLEN | CILK_FRAME_SUSPENDED;
+        sf->worker = 0;
+
+        if (is_loot)
+            __cilkrts_put_stack(ff, sf);
+
+        /* perform any system-dependent action, such as saving the
+           state of the stack */
+        __cilkrts_make_unrunnable_sysdep(w, ff, sf, is_loot, why);
+    }
+}
+
+
+/* Push the next full frame to be made active in this worker and increment its
+ * join counter.  __cilkrts_push_next_frame and pop_next_frame work on a
+ * one-element queue.  This queue is used to communicate across the runtime
+ * from the code that wants to activate a frame to the code that can actually
+ * begin execution on that frame.  They are asymetrical in that push
+ * increments the join counter but pop does not decrement it.  Rather, a
+ * single push/pop combination makes a frame active and increments its join
+ * counter once. */
+void __cilkrts_push_next_frame(__cilkrts_worker *w, full_frame *ff)
+{
+    CILK_ASSERT(ff);
+    CILK_ASSERT(!w->l->next_frame_ff);
+    incjoin(ff);
+    w->l->next_frame_ff = ff;
+}
+
+/* Get the next full-frame to be made active in this worker.  The join count
+ * of the full frame will have been incremented by the corresponding push
+ * event.  See __cilkrts_push_next_frame, above.
+ */
+static full_frame *pop_next_frame(__cilkrts_worker *w)
+{
+    full_frame *ff;
+    ff = w->l->next_frame_ff;
+    // Remove the frame from the next_frame field.
+    //
+    // If this is a user worker, then there is a chance that another worker
+    // from our team could push work into our next_frame (if it is the last
+    // worker doing work for this team).  The other worker's setting of the
+    // next_frame could race with our setting of next_frame to NULL.  This is
+    // the only possible race condition on next_frame.  However, if next_frame
+    // has a non-NULL value, then it means the team still has work to do, and
+    // there is no chance of another team member populating next_frame.  Thus,
+    // it is safe to set next_frame to NULL, if it was populated.  There is no
+    // need for an atomic op.
+    if (NULL != ff) {
+        w->l->next_frame_ff = NULL;
+    }
+    return ff;
+}
+
+/*
+ * Identify the single worker that is allowed to cross a sync in this frame.  A
+ * thief should call this function when it is the first to steal work from a
+ * user worker.  "First to steal work" may mean that there has been parallelism
+ * in the user worker before, but the whole team sync'd, and this is the first
+ * steal after that.
+ *
+ * This should happen while holding the worker and frame lock.
+ */
+static void set_sync_master(__cilkrts_worker *w, full_frame *ff)
+{
+    w->l->last_full_frame = ff;
+    ff->sync_master = w;
+}
+
+/*
+ * The sync that ends all parallelism for a particular user worker is about to
+ * be crossed.  Decouple the worker and frame.
+ *
+ * No locks need to be held since the user worker isn't doing anything, and none
+ * of the system workers can steal from it.  But unset_sync_master() should be
+ * called before the user worker knows about this work (i.e., before it is
+ * inserted into the w->l->next_frame_ff is set).
+ */
+static void unset_sync_master(__cilkrts_worker *w, full_frame *ff)
+{
+    CILK_ASSERT(WORKER_USER == w->l->type);
+    CILK_ASSERT(ff->sync_master == w);
+    ff->sync_master = NULL;
+    w->l->last_full_frame = NULL;
+}
+
+/********************************************************************
+ * THE protocol:
+ ********************************************************************/
+/*
+ * This is a protocol for work stealing that minimizes the overhead on
+ * the victim.
+ *
+ * The protocol uses three shared pointers into the worker's deque:
+ * - T - the "tail"
+ * - H - the "head"
+ * - E - the "exception"  NB: In this case, "exception" has nothing to do
+ * with C++ throw-catch exceptions -- it refers only to a non-normal return,
+ * i.e., a steal or similar scheduling exception.
+ *
+ * with H <= E, H <= T.  
+ *
+ * Stack frames SF, where H <= E < T, are available for stealing. 
+ *
+ * The worker operates on the T end of the stack.  The frame being
+ * worked on is not on the stack.  To make a continuation available for
+ * stealing the worker pushes a from onto the stack: stores *T++ = SF.
+ * To return, it pops the frame off the stack: obtains SF = *--T.
+ *
+ * After decrementing T, the condition E > T signals to the victim that
+ * it should invoke the runtime system's "THE" exception handler.  The
+ * pointer E can become INFINITY, in which case the victim must invoke
+ * the THE exception handler as soon as possible.
+ *
+ * See "The implementation of the Cilk-5 multithreaded language", PLDI 1998,
+ * http://portal.acm.org/citation.cfm?doid=277652.277725, for more information
+ * on the THE protocol.
+ */
+
+/* the infinity value of E */
+#define EXC_INFINITY  ((__cilkrts_stack_frame **) (-1))
+
+static void increment_E(__cilkrts_worker *victim)
+{
+    __cilkrts_stack_frame *volatile *tmp;
+
+    // The currently executing worker must own the worker lock to touch
+    // victim->exc
+    ASSERT_WORKER_LOCK_OWNED(victim);
+
+    tmp = victim->exc;
+    if (tmp != EXC_INFINITY) {
+        /* On most x86 this pair of operations would be slightly faster
+           as an atomic exchange due to the implicit memory barrier in
+           an atomic instruction. */
+        victim->exc = tmp + 1;
+        __cilkrts_fence();
+    }
+}
+
+static void decrement_E(__cilkrts_worker *victim)
+{
+    __cilkrts_stack_frame *volatile *tmp;
+
+    // The currently executing worker must own the worker lock to touch
+    // victim->exc
+    ASSERT_WORKER_LOCK_OWNED(victim);
+
+    tmp = victim->exc;
+    if (tmp != EXC_INFINITY) {
+        /* On most x86 this pair of operations would be slightly faster
+           as an atomic exchange due to the implicit memory barrier in
+           an atomic instruction. */
+        victim->exc = tmp - 1;
+        __cilkrts_fence(); /* memory fence not really necessary */
+    }
+}
+
+#if 0
+/* for now unused, will be necessary if we implement abort */
+static void signal_THE_exception(__cilkrts_worker *wparent)
+{
+    wparent->exc = EXC_INFINITY;
+    __cilkrts_fence();
+}
+#endif
+
+static void reset_THE_exception(__cilkrts_worker *w)
+{
+    // The currently executing worker must own the worker lock to touch
+    // w->exc
+    ASSERT_WORKER_LOCK_OWNED(w);
+
+    w->exc = w->head;
+    __cilkrts_fence();
+}
+
+/* conditions under which victim->head can be stolen: */
+static int can_steal_from(__cilkrts_worker *victim)
+{
+    return ((victim->head < victim->tail) && 
+            (victim->head < victim->protected_tail));
+}
+
+/* Return TRUE if the frame can be stolen, false otherwise */
+static int dekker_protocol(__cilkrts_worker *victim)
+{
+    // increment_E and decrement_E are going to touch victim->exc.  The
+    // currently executing worker must own victim's lock before they can
+    // modify it
+    ASSERT_WORKER_LOCK_OWNED(victim);
+
+    /* ASSERT(E >= H); */
+
+    increment_E(victim);
+
+    /* ASSERT(E >= H + 1); */
+    if (can_steal_from(victim)) {
+        /* success, we can steal victim->head and set H <- H + 1
+           in detach() */
+        return 1;
+    } else {
+        /* failure, restore previous state */
+        decrement_E(victim);
+        return 0;    
+    }
+}
+
+
+/* Link PARENT and CHILD in the spawn tree */
+static full_frame *make_child(__cilkrts_worker *w, 
+                              full_frame *parent_ff,
+                              __cilkrts_stack_frame *child_sf,
+                              cilk_fiber *fiber) 
+{
+    full_frame *child_ff = __cilkrts_make_full_frame(w, child_sf);
+
+    child_ff->parent = parent_ff;
+    push_child(parent_ff, child_ff);
+
+    //DBGPRINTF("%d-          make_child - child_frame: %p, parent_frame: %p, child_sf: %p\n"
+    //    "            parent - parent: %p, left_sibling: %p, right_sibling: %p, rightmost_child: %p\n"
+    //    "            child  - parent: %p, left_sibling: %p, right_sibling: %p, rightmost_child: %p\n",
+    //          w->self, child, parent, child_sf,
+    //          parent->parent, parent->left_sibling, parent->right_sibling, parent->rightmost_child,
+    //          child->parent, child->left_sibling, child->right_sibling, child->rightmost_child);
+    CILK_ASSERT(parent_ff->call_stack);
+    child_ff->is_call_child = (fiber == NULL);
+
+    /* PLACEHOLDER_FIBER is used as non-null marker indicating that
+       child should be treated as a spawn child even though we have not
+       yet assigned a real fiber to its parent. */
+    if (fiber == PLACEHOLDER_FIBER)
+        fiber = NULL; /* Parent actually gets a null fiber, for now */
+
+    /* perform any system-dependent actions, such as capturing
+       parameter passing information */
+    /*__cilkrts_make_child_sysdep(child, parent);*/
+
+    /* Child gets reducer map and stack of parent.
+       Parent gets a new map and new stack. */
+    child_ff->fiber_self = parent_ff->fiber_self;
+    child_ff->sync_master = NULL;
+
+    if (child_ff->is_call_child) {
+        /* Cause segfault on any attempted access.  The parent gets
+           the child map and stack when the child completes. */
+        parent_ff->fiber_self = 0;
+    } else {
+        parent_ff->fiber_self = fiber;
+    }
+
+    incjoin(parent_ff);
+    return child_ff;
+}
+
+static inline __cilkrts_stack_frame *__cilkrts_advance_frame(__cilkrts_stack_frame *sf)
+{
+    __cilkrts_stack_frame *p = sf->call_parent;
+    sf->call_parent = 0;
+    return p;
+}
+
+/* w should be the currently executing worker.  
+ * loot_sf is the youngest stack frame in the call stack being 
+ *   unrolled (i.e., the most deeply nested stack frame.)
+ *
+ * When this method is called for a steal, loot_sf should be on a
+ * victim worker which is different from w.
+ * For CILK_FORCE_REDUCE, the victim worker will equal w.
+ *
+ * Before execution, the __cilkrts_stack_frame's have pointers from
+ * older to younger, i.e., a __cilkrts_stack_frame points to parent.
+ *
+ * This method creates a full frame for each __cilkrts_stack_frame in
+ * the call stack, with each full frame also pointing to its parent. 
+ *
+ * The method returns the full frame created for loot_sf, i.e., the
+ * youngest full frame.
+ */
+static full_frame *unroll_call_stack(__cilkrts_worker *w, 
+                                     full_frame *ff, 
+                                     __cilkrts_stack_frame *const loot_sf)
+{
+    __cilkrts_stack_frame *sf = loot_sf;
+    __cilkrts_stack_frame *rev_sf = 0;
+    __cilkrts_stack_frame *t_sf;
+
+    CILK_ASSERT(sf);
+    /*CILK_ASSERT(sf->call_parent != sf);*/
+
+    /* The leafmost frame is unsynched. */
+    if (sf->worker != w)
+        sf->flags |= CILK_FRAME_UNSYNCHED;
+
+    /* Reverse the call stack to make a linked list ordered from parent
+       to child.  sf->call_parent points to the child of SF instead of
+       the parent.  */
+    do {
+        t_sf = (sf->flags & (CILK_FRAME_DETACHED|CILK_FRAME_STOLEN|CILK_FRAME_LAST))? 0 : sf->call_parent;
+        sf->call_parent = rev_sf;
+        rev_sf = sf;
+        sf = t_sf;
+    } while (sf);
+    sf = rev_sf;
+
+    /* Promote each stack frame to a full frame in order from parent
+       to child, following the reversed list we just built. */
+    make_unrunnable(w, ff, sf, sf == loot_sf, "steal 1");
+    /* T is the *child* of SF, because we have reversed the list */
+    for (t_sf = __cilkrts_advance_frame(sf); t_sf;
+         sf = t_sf, t_sf = __cilkrts_advance_frame(sf)) {
+        ff = make_child(w, ff, t_sf, NULL);
+        make_unrunnable(w, ff, t_sf, t_sf == loot_sf, "steal 2");
+    }
+
+    /* XXX What if the leafmost frame does not contain a sync
+       and this steal is from promote own deque? */
+    /*sf->flags |= CILK_FRAME_UNSYNCHED;*/
+
+    CILK_ASSERT(!sf->call_parent);
+    return ff;
+}
+
+/* detach the top of the deque frame from the VICTIM and install a new
+   CHILD frame in its place */
+static void detach_for_steal(__cilkrts_worker *w,
+                             __cilkrts_worker *victim,
+                             cilk_fiber* fiber)
+{
+    /* ASSERT: we own victim->lock */
+
+    full_frame *parent_ff, *child_ff, *loot_ff;
+    __cilkrts_stack_frame *volatile *h;
+    __cilkrts_stack_frame *sf;
+
+    w->l->team = victim->l->team;
+
+    CILK_ASSERT(w->l->frame_ff == 0 || w == victim);
+
+    h = victim->head;
+
+    CILK_ASSERT(*h);
+
+    victim->head = h + 1;
+
+    parent_ff = victim->l->frame_ff;
+    BEGIN_WITH_FRAME_LOCK(w, parent_ff) {
+        /* parent no longer referenced by victim */
+        decjoin(parent_ff);
+
+        /* obtain the victim call stack */
+        sf = *h;
+
+        /* perform system-dependent normalizations */
+        /*__cilkrts_normalize_call_stack_on_steal(sf);*/
+
+        /* unroll PARENT_FF with call stack SF, adopt the youngest
+           frame LOOT.  If loot_ff == parent_ff, then we hold loot_ff->lock,
+           otherwise, loot_ff is newly created and we can modify it without
+           holding its lock. */
+        loot_ff = unroll_call_stack(w, parent_ff, sf);
+
+        #if REDPAR_DEBUG >= 3
+        fprintf(stderr, "[W=%d, victim=%d, desc=detach, parent_ff=%p, loot=%p]\n",
+                w->self, victim->self,
+                parent_ff, loot_ff);
+        #endif
+
+        if (WORKER_USER == victim->l->type &&
+            NULL == victim->l->last_full_frame) {
+            // Mark this looted frame as special: only the original user worker
+            // may cross the sync.
+            // 
+            // This call is a shared access to
+            // victim->l->last_full_frame.
+            set_sync_master(victim, loot_ff);
+        }
+
+        /* LOOT is the next frame that the thief W is supposed to
+           run, unless the thief is stealing from itself, in which
+           case the thief W == VICTIM executes CHILD and nobody
+           executes LOOT. */
+        if (w == victim) {
+            /* Pretend that frame has been stolen */
+            loot_ff->call_stack->flags |= CILK_FRAME_UNSYNCHED;
+            loot_ff->simulated_stolen = 1;
+        }
+        else
+            __cilkrts_push_next_frame(w, loot_ff);
+
+        // After this "push_next_frame" call, w now owns loot_ff.
+        child_ff = make_child(w, loot_ff, 0, fiber);
+
+        BEGIN_WITH_FRAME_LOCK(w, child_ff) {
+            /* install child in the victim's work queue, taking
+               the parent_ff's place */
+            /* child is referenced by victim */
+            incjoin(child_ff);
+
+            // With this call, w is bestowing ownership of the newly
+            // created frame child_ff to the victim, and victim is
+            // giving up ownership of parent_ff.
+            //
+            // Worker w will either take ownership of parent_ff
+            // if parent_ff == loot_ff, or parent_ff will be
+            // suspended.
+            //
+            // Note that this call changes the victim->frame_ff
+            // while the victim may be executing.
+            make_runnable(victim, child_ff);
+        } END_WITH_FRAME_LOCK(w, child_ff);
+    } END_WITH_FRAME_LOCK(w, parent_ff);
+}
+
+/**
+ * @brief cilk_fiber_proc that resumes user code after a successful
+ * random steal.
+
+ * This function longjmps back into the user code whose state is
+ * stored in cilk_fiber_get_data(fiber)->resume_sf.  The stack pointer
+ * is adjusted so that the code resumes on the specified fiber stack
+ * instead of its original stack.
+ *
+ * This method gets executed only on a fiber freshly allocated from a
+ * pool.
+ *
+ * @param fiber   The fiber being used to resume user code.
+ * @param arg     Unused.
+ */
+static
+void fiber_proc_to_resume_user_code_for_random_steal(cilk_fiber *fiber)
+{
+    cilk_fiber_data *data = cilk_fiber_get_data(fiber);
+    __cilkrts_stack_frame* sf = data->resume_sf;
+    full_frame *ff;
+
+    CILK_ASSERT(sf);
+
+    // When we pull the resume_sf out of the fiber to resume it, clear
+    // the old value.
+    data->resume_sf = NULL;
+    CILK_ASSERT(sf->worker == data->owner);
+    ff = sf->worker->l->frame_ff;
+
+    // For Win32, we need to overwrite the default exception handler
+    // in this function, so that when the OS exception handling code
+    // walks off the top of the current Cilk stack, it reaches our stub
+    // handler.
+    
+    // Also, this function needs to be wrapped into a try-catch block
+    // so the compiler generates the appropriate exception information
+    // in this frame.
+    
+    // TBD: IS THIS HANDLER IN THE WRONG PLACE?  Can we longjmp out of
+    // this function (and does it matter?)
+#if defined(_WIN32) && !defined(_WIN64)
+    install_exception_stub_handler();
+    __try 
+#endif
+    {
+        char* new_sp = sysdep_reset_jump_buffers_for_resume(fiber, ff, sf);
+        
+        // Notify the Intel tools that we're stealing code
+        ITT_SYNC_ACQUIRED(sf->worker);
+        NOTIFY_ZC_INTRINSIC("cilk_continue", sf);
+
+        // TBD: We'd like to move TBB-interop methods into the fiber
+        // eventually.
+        cilk_fiber_invoke_tbb_stack_op(fiber, CILK_TBB_STACK_ADOPT);
+        
+        sf->flags &= ~CILK_FRAME_SUSPENDED;
+
+        // longjmp to user code.  Don't process exceptions here,
+        // because we are resuming a stolen frame.
+        sysdep_longjmp_to_sf(new_sp, sf, NULL);
+        /*NOTREACHED*/
+        // Intel's C compiler respects the preceding lint pragma
+    }
+#if defined(_WIN32) && !defined(_WIN64)
+    __except (CILK_ASSERT(!"should not execute the the stub filter"),
+              EXCEPTION_EXECUTE_HANDLER)
+    {
+        // If we are here, that means something very wrong
+        // has happened in our exception processing...
+        CILK_ASSERT(! "should not be here!");
+    }
+#endif
+}
+
+static void random_steal(__cilkrts_worker *w)
+{
+    __cilkrts_worker *victim = NULL;
+    cilk_fiber *fiber = NULL;
+    int n;
+    int success = 0;
+    int32_t victim_id;
+
+    // Nothing's been stolen yet. When true, this will flag
+    // setup_for_execution_pedigree to increment the pedigree
+    w->l->work_stolen = 0;
+
+    /* If the user has disabled stealing (using the debugger) we fail */
+    if (__builtin_expect(w->g->stealing_disabled, 0))
+        return;
+
+    CILK_ASSERT(w->l->type == WORKER_SYSTEM || w->l->team == w);
+
+    /* If there is only one processor work can still be stolen.
+       There must be only one worker to prevent stealing. */
+    CILK_ASSERT(w->g->total_workers > 1);
+
+    /* pick random *other* victim */
+    n = myrand(w) % (w->g->total_workers - 1);
+    if (n >= w->self)
+        ++n;
+
+    // If we're replaying a log, override the victim.  -1 indicates that
+    // we've exhausted the list of things this worker stole when we recorded
+    // the log so just return.  If we're not replaying a log,
+    // replay_get_next_recorded_victim() just returns the victim ID passed in.
+    n = replay_get_next_recorded_victim(w, n);
+    if (-1 == n)
+        return;
+
+    victim = w->g->workers[n];
+
+    START_INTERVAL(w, INTERVAL_FIBER_ALLOCATE) {
+        /* Verify that we can get a stack.  If not, no need to continue. */
+        fiber = cilk_fiber_allocate(&w->l->fiber_pool);
+    } STOP_INTERVAL(w, INTERVAL_FIBER_ALLOCATE);
+
+
+    if (NULL == fiber) {
+#if FIBER_DEBUG >= 2
+        fprintf(stderr, "w=%d: failed steal because we could not get a fiber\n",
+                w->self);
+#endif        
+        return;
+    }
+
+    /* do not steal from self */
+    CILK_ASSERT (victim != w);
+
+    /* Execute a quick check before engaging in the THE protocol.
+       Avoid grabbing locks if there is nothing to steal. */
+    if (!can_steal_from(victim)) {
+        NOTE_INTERVAL(w, INTERVAL_STEAL_FAIL_EMPTYQ);
+        START_INTERVAL(w, INTERVAL_FIBER_DEALLOCATE) {
+            int ref_count = cilk_fiber_remove_reference(fiber, &w->l->fiber_pool);
+            // Fibers we use when trying to steal should not be active,
+            // and thus should not have any other references.
+            CILK_ASSERT(0 == ref_count);
+        } STOP_INTERVAL(w, INTERVAL_FIBER_DEALLOCATE);
+        return;
+    }
+    
+    /* Attempt to steal work from the victim */
+    if (worker_trylock_other(w, victim)) {
+        if (w->l->type == WORKER_USER && victim->l->team != w) {
+
+            // Fail to steal if this is a user worker and the victim is not
+            // on this team.  If a user worker were allowed to steal work
+            // descended from another user worker, the former might not be
+            // done with its work by the time it was needed to resume and
+            // unbind.  Therefore, user workers are not permitted to change
+            // teams.
+
+            // There is no race on the victim's team because the victim cannot
+            // change its team until it runs out of work to do, at which point
+            // it will try to take out its own lock, and this worker already
+            // holds it.
+            NOTE_INTERVAL(w, INTERVAL_STEAL_FAIL_USER_WORKER);
+
+        } else if (victim->l->frame_ff) {
+            // A successful steal will change victim->frame_ff, even
+            // though the victim may be executing.  Thus, the lock on
+            // the victim's deque is also protecting victim->frame_ff.
+            if (dekker_protocol(victim)) {
+                int proceed_with_steal = 1; // optimistic
+
+                // If we're replaying a log, verify that this the correct frame
+                // to steal from the victim
+                if (! replay_match_victim_pedigree(w, victim))
+                {
+                    // Abort the steal attempt. decrement_E(victim) to
+                    // counter the increment_E(victim) done by the
+                    // dekker protocol
+                    decrement_E(victim);
+                    proceed_with_steal = 0;
+                }
+
+                if (proceed_with_steal)
+                {
+                    START_INTERVAL(w, INTERVAL_STEAL_SUCCESS) {
+                        success = 1;
+                        detach_for_steal(w, victim, fiber);
+                        victim_id = victim->self;
+
+                        #if REDPAR_DEBUG >= 1
+                        fprintf(stderr, "Wkr %d stole from victim %d, fiber = %p\n",
+                                w->self, victim->self, fiber);
+                        #endif
+
+                        // The use of victim->self contradicts our
+                        // classification of the "self" field as 
+                        // local.  But since this code is only for
+                        // debugging, it is ok.
+                        DBGPRINTF ("%d-%p: Stealing work from worker %d\n"
+                            "            sf: %p, call parent: %p\n",
+                            w->self, GetCurrentFiber(), victim->self,
+                            w->l->next_frame_ff->call_stack,
+                            w->l->next_frame_ff->call_stack->call_parent);
+                    } STOP_INTERVAL(w, INTERVAL_STEAL_SUCCESS);
+                }  // end if(proceed_with_steal)
+            } else {
+                NOTE_INTERVAL(w, INTERVAL_STEAL_FAIL_DEKKER);
+            }
+        } else {
+            NOTE_INTERVAL(w, INTERVAL_STEAL_FAIL_EMPTYQ);
+        }
+        worker_unlock_other(w, victim);
+    } else {
+        NOTE_INTERVAL(w, INTERVAL_STEAL_FAIL_LOCK);
+    }
+
+    // Record whether work was stolen.  When true, this will flag
+    // setup_for_execution_pedigree to increment the pedigree
+    w->l->work_stolen = success;
+
+    if (0 == success) {
+        // failed to steal work.  Return the fiber to the pool.
+        START_INTERVAL(w, INTERVAL_FIBER_DEALLOCATE) {
+            int ref_count = cilk_fiber_remove_reference(fiber, &w->l->fiber_pool);
+            // Fibers we use when trying to steal should not be active,
+            // and thus should not have any other references.
+            CILK_ASSERT(0 == ref_count);
+        } STOP_INTERVAL(w, INTERVAL_FIBER_DEALLOCATE);
+    }
+    else
+    {
+        // Since our steal was successful, finish initialization of
+        // the fiber.
+        cilk_fiber_reset_state(fiber,
+                               fiber_proc_to_resume_user_code_for_random_steal);
+        // Record the pedigree of the frame that w has stolen.
+        // record only if CILK_RECORD_LOG is set
+        replay_record_steal(w, victim_id);
+    }
+}
+
+
+
+/**
+ * At a provably good steal, we need to transfer the child reducer map
+ * from ff->children_reducer_map into v->reducer_map, where v is the
+ * worker that resumes execution of ff.
+ *
+ * Normally, we have v == w, where w is the currently executing
+ * worker.  In the case where we are resuming a team leader on a user
+ * worker, however, v might differ from w.
+
+ * Thus, this, operation is a no-op, since we can't really move
+ * ff->children_reducer_map into w here.
+ *
+ * Instead, this work is done in setup_for_execution_reducers().
+ */
+static inline void provably_good_steal_reducers(__cilkrts_worker *w,
+                                                full_frame       *ff)
+{
+    // No-op.
+}
+
+/* at a provably good steal, incorporate the accumulated exceptions of
+   children into the parent's exception */
+static void provably_good_steal_exceptions(__cilkrts_worker *w, 
+                                           full_frame       *ff)
+{
+    // ASSERT: we own ff->lock
+    ff->pending_exception =
+        __cilkrts_merge_pending_exceptions(w,
+                                           ff->child_pending_exception,
+                                           ff->pending_exception);
+    ff->child_pending_exception = NULL;
+}
+
+/* At sync discard the frame's old stack and take the leftmost child's. */
+static void provably_good_steal_stacks(__cilkrts_worker *w, full_frame *ff)
+{
+    CILK_ASSERT(NULL == ff->fiber_self);
+    ff->fiber_self = ff->fiber_child;
+    ff->fiber_child = NULL;
+}
+
+static void __cilkrts_mark_synched(full_frame *ff)
+{
+    ff->call_stack->flags &= ~CILK_FRAME_UNSYNCHED;
+    ff->simulated_stolen = 0;
+}
+
+static
+enum provably_good_steal_t provably_good_steal(__cilkrts_worker *w,
+                                               full_frame       *ff)
+{
+    // ASSERT: we hold w->lock and ff->lock
+
+    enum provably_good_steal_t result = ABANDON_EXECUTION;
+
+    // If the current replay entry is a sync record matching the worker's
+    // pedigree, AND this isn't the last child to the sync, return
+    // WAIT_FOR_CONTINUE to indicate that the caller should loop until
+    // we find the right frame to steal and CONTINUE_EXECUTION is returned.
+    int match_found = replay_match_sync_pedigree(w);
+    if (match_found && (0 != simulate_decjoin(ff)))
+        return WAIT_FOR_CONTINUE;
+
+    START_INTERVAL(w, INTERVAL_PROVABLY_GOOD_STEAL) {
+        if (decjoin(ff) == 0) {
+            provably_good_steal_reducers(w, ff);
+            provably_good_steal_exceptions(w, ff);
+            provably_good_steal_stacks(w, ff);
+            __cilkrts_mark_synched(ff);
+
+            // If the original owner wants this frame back (to resume
+            // it on its original thread) pass it back now.
+            if (NULL != ff->sync_master) {
+                // The frame wants to go back and be executed by the original
+                // user thread.  We can throw caution to the wind and push the
+                // frame straight onto its queue because the only way we have
+                // gotten to this point of being able to continue execution of
+                // the frame is if the original user worker is spinning without
+                // work.
+
+                unset_sync_master(w->l->team, ff);
+                __cilkrts_push_next_frame(w->l->team, ff);
+
+                // If this is the team leader we're not abandoning the work
+                if (w == w->l->team)
+                    result = CONTINUE_EXECUTION;
+            } else {
+                __cilkrts_push_next_frame(w, ff);
+                result = CONTINUE_EXECUTION;  // Continue working on this thread
+            }
+
+            // The __cilkrts_push_next_frame() call changes ownership
+            // of ff to the specified worker.
+        }
+    } STOP_INTERVAL(w, INTERVAL_PROVABLY_GOOD_STEAL);
+
+    // Only write a SYNC record if:
+    // - We're recording a log *AND*
+    // - We're the worker continuing from this sync
+    replay_record_sync(w, result == CONTINUE_EXECUTION);
+
+    // If we're replaying a log, and matched a sync from the log, mark the
+    // sync record seen if the sync isn't going to be abandoned.
+    replay_advance_from_sync (w, match_found, result == CONTINUE_EXECUTION);
+
+    return result;
+}
+
+static void unconditional_steal(__cilkrts_worker *w,
+                                full_frame *ff)
+{
+    // ASSERT: we hold ff->lock
+
+    START_INTERVAL(w, INTERVAL_UNCONDITIONAL_STEAL) {
+        decjoin(ff);
+        __cilkrts_push_next_frame(w, ff);
+    } STOP_INTERVAL(w, INTERVAL_UNCONDITIONAL_STEAL);
+}
+
+
+/* CHILD is about to die.  Give its exceptions to a sibling or to the
+   parent.  */
+static inline void splice_exceptions_for_call(__cilkrts_worker *w,
+                                              full_frame *parent_ff,
+                                              full_frame *child_ff)
+{
+    // ASSERT: We own parent_ff->lock
+    CILK_ASSERT(child_ff->is_call_child);
+    CILK_ASSERT(NULL == child_ff->right_pending_exception);
+    CILK_ASSERT(NULL == parent_ff->pending_exception);
+    
+    parent_ff->pending_exception = child_ff->pending_exception;
+    child_ff->pending_exception = NULL;
+}
+
+/**
+ * Merge exceptions for a dying child. 
+ *
+ * @param w                   The currently executing worker.
+ * @param ff                  The child frame that is dying.
+ * @param left_exception_ptr  Pointer to the exception that is to our left.
+ */ 
+static inline
+void splice_exceptions_for_spawn(__cilkrts_worker *w,
+                                 full_frame *ff,
+                                 struct pending_exception_info **left_exception_ptr)
+{
+    // ASSERT: parent_ff == child_ff->parent.
+    // ASSERT: We own parent_ff->lock
+
+    // Merge current exception into the slot where the left
+    // exception should go.
+    *left_exception_ptr =
+        __cilkrts_merge_pending_exceptions(w,
+                                           *left_exception_ptr,
+                                           ff->pending_exception);
+    ff->pending_exception = NULL;
+
+
+    // Merge right exception into the slot where the left exception
+    // should go.
+    *left_exception_ptr =
+        __cilkrts_merge_pending_exceptions(w,
+                                           *left_exception_ptr,
+                                           ff->right_pending_exception);
+    ff->right_pending_exception = NULL;
+}
+
+
+static inline void splice_stacks_for_call(__cilkrts_worker *w,
+                                          full_frame *parent_ff,
+                                          full_frame *child_ff)
+{
+#if CILK_LIB_DEBUG
+    if (parent_ff->call_stack)
+        CILK_ASSERT(!(parent_ff->call_stack->flags & CILK_FRAME_MBZ));
+#endif
+
+    /* A synched frame does not have accumulated child reducers. */
+    CILK_ASSERT(!child_ff->fiber_child);
+    CILK_ASSERT(child_ff->is_call_child);
+
+    /* An attached parent has no self fiber.  It may have
+       accumulated child fibers or child owners, which should be
+       ignored until sync. */
+    CILK_ASSERT(!parent_ff->fiber_self);
+    parent_ff->fiber_self = child_ff->fiber_self;
+    child_ff->fiber_self = NULL;
+}
+
+static void finalize_child_for_call(__cilkrts_worker *w,
+                                    full_frame *parent_ff,
+                                    full_frame *child_ff)
+{
+    // ASSERT: we hold w->lock and parent_ff->lock
+    
+    START_INTERVAL(w, INTERVAL_FINALIZE_CHILD) {
+        CILK_ASSERT(child_ff->is_call_child);
+        CILK_ASSERT(child_ff->join_counter == 0);
+        CILK_ASSERT(!child_ff->rightmost_child);
+        CILK_ASSERT(child_ff == parent_ff->rightmost_child);
+
+        // CHILD is about to die. 
+        // Splicing out reducers is a no-op for a call since
+        // w->reducer_map should already store the correct 
+        // reducer map.
+        
+        // ASSERT there are no maps left to reduce.
+        CILK_ASSERT(NULL == child_ff->children_reducer_map);
+        CILK_ASSERT(NULL == child_ff->right_reducer_map);
+        
+        splice_exceptions_for_call(w, parent_ff, child_ff);
+
+        splice_stacks_for_call(w, parent_ff, child_ff);
+
+        /* remove CHILD from list of children of PARENT */
+        unlink_child(parent_ff, child_ff);
+
+        /* continue with the parent. */
+        unconditional_steal(w, parent_ff);
+        __cilkrts_destroy_full_frame(w, child_ff);
+    } STOP_INTERVAL(w, INTERVAL_FINALIZE_CHILD);
+}
+
+
+/**
+ * The invariant on ff->children_reducer_map is that when ff is
+ * synched and when we are about to resume execution of ff, at least
+ * one of ff->children_reducer_map and w->reducer_map must be NULL.
+ *
+ * Consider the two possibilities before resuming execution of ff:
+ *
+ * 1.  Suppose ff is synched and suspended.  Then either
+ *
+ *     (a) ff->children_reducer_map stores the reducer map that w
+ *         should use, where w is the worker resuming execution of ff, 
+ *         OR
+ *     (b) w already has a user map, and ff->children_reducer_map is NULL. 
+ *
+ *     Case (a) happens when we are resuming execution of ff as a
+ *     provably good steal.  In this case, w->reducer_map should be
+ *     NULL and ff->children_reducer_map is valid.  To resume
+ *     execution of ff on w, set w->reducer_map to
+ *     ff->children_reducer_map.
+ * 
+ *     Case (b) occurs when we resume execution of ff because ff is a
+ *     called child.  Then, ff->children_reducer_map should be NULL,
+ *     and w should already have a valid reducer map when resuming
+ *     execution of ff.  We resume execution of ff without changing
+ *     w->reducer_map.
+ *
+ * 2. Suppose frame ff is not synched (i.e., it is active and might have
+ *    active children).   Then ff->children_reducer_map is the slot for
+ *    storing the reducer map from ff's leftmost child, as in the reducer
+ *    protocol.   The runtime may resume execution of ff while it is not 
+ *    synched only because of a steal.
+ *    In this case, while we are resuming ff, ff->children_reducer_map
+ *    may be non-NULL (because one of ff's children has completed).
+ *    We resume execution of ff without changing w->reducer_map.
+ */ 
+static void setup_for_execution_reducers(__cilkrts_worker *w,
+                                         full_frame *ff)
+{
+    // We only need to move ff->children_reducer_map into
+    // w->reducer_map in case 1(a).
+    //
+    // First check whether ff is synched.
+    __cilkrts_stack_frame *sf = ff->call_stack;
+    if (!(sf->flags & CILK_FRAME_UNSYNCHED)) {
+        // In this case, ff is synched. (Case 1).
+        CILK_ASSERT(!ff->rightmost_child);
+
+        // Test whether we are in case 1(a) and have
+        // something to do.  Note that if both
+        // ff->children_reducer_map and w->reducer_map are NULL, we
+        // can't distinguish between cases 1(a) and 1(b) here.
+        if (ff->children_reducer_map) {
+            // We are in Case 1(a).
+            CILK_ASSERT(!w->reducer_map);
+            w->reducer_map = ff->children_reducer_map;
+            ff->children_reducer_map = NULL;
+        }
+    }
+}
+
+static void setup_for_execution_exceptions(__cilkrts_worker *w, 
+                                           full_frame *ff)
+{
+    CILK_ASSERT(NULL == w->l->pending_exception);
+    w->l->pending_exception = ff->pending_exception;
+    ff->pending_exception = NULL;
+}
+
+#if 0 /* unused */
+static void setup_for_execution_stack(__cilkrts_worker *w, 
+                                      full_frame *ff)
+{
+}
+#endif
+
+/*
+ * setup_for_execution_pedigree
+ *
+ * Copies the pedigree information from the frame we're resuming to the
+ * worker.  Increments the pedigree if this is work that has been stolen
+ * to match the increment on a return from a spawn helper.
+ */
+static void setup_for_execution_pedigree(__cilkrts_worker *w)
+{
+    int pedigree_unsynched;
+    __cilkrts_stack_frame *sf = w->current_stack_frame;
+
+    CILK_ASSERT(NULL != sf);
+
+    // If this isn't an ABI 1 or later frame, there's no pedigree information
+    if (0 == CILK_FRAME_VERSION_VALUE(sf->flags))
+        return;
+
+    // Note whether the pedigree is unsynched and clear the flag before
+    // we forget
+    pedigree_unsynched = sf->flags & CILK_FRAME_SF_PEDIGREE_UNSYNCHED;
+    sf->flags &= ~CILK_FRAME_SF_PEDIGREE_UNSYNCHED;
+
+    // If we're just marshalling onto this worker, do not increment
+    // the rank since that wouldn't happen in a sequential execution
+    if (w->l->work_stolen || pedigree_unsynched)
+    {
+        if (w->l->work_stolen)
+            w->pedigree.rank = sf->parent_pedigree.rank + 1;
+        else
+            w->pedigree.rank = sf->parent_pedigree.rank;
+    }
+
+    w->pedigree.parent = sf->parent_pedigree.parent;
+    w->l->work_stolen = 0;
+}
+
+static void setup_for_execution(__cilkrts_worker *w, 
+                                full_frame *ff,
+                                int is_return_from_call)
+{
+    // ASSERT: We own w->lock and ff->lock || P == 1
+
+    setup_for_execution_reducers(w, ff);
+    setup_for_execution_exceptions(w, ff);
+    /*setup_for_execution_stack(w, ff);*/
+
+    ff->call_stack->worker = w;
+    w->current_stack_frame = ff->call_stack;
+
+    // If this is a return from a call, leave the pedigree alone
+    if (! is_return_from_call)
+        setup_for_execution_pedigree(w);
+
+    __cilkrts_setup_for_execution_sysdep(w, ff);
+
+    w->head = w->tail = w->l->ltq;
+    reset_THE_exception(w);
+
+    make_runnable(w, ff);
+}
+
+
+/*
+ * Called by the scheduling fiber, right before
+ * resuming a sf/ff for user code.
+ *
+ * This method associates the specified sf with the worker.
+ *
+ * It also asserts that w, ff, and sf all have the expected properties
+ * for resuming user code.
+ */ 
+void scheduling_fiber_prepare_to_resume_user_code(__cilkrts_worker *w,
+                                                  full_frame *ff,
+                                                  __cilkrts_stack_frame *sf)
+{
+    w->current_stack_frame = sf;
+    sf->worker = w;
+
+    // Lots of debugging checks on the state of the fiber we might be
+    // resuming.
+#if FIBER_DEBUG >= 1
+#   if FIBER_DEBUG >= 3
+    {
+        fprintf(stderr, "w=%d: ff=%p, sf=%p. about to resume user code\n",
+                w->self, ff, sf);
+    }
+#   endif
+
+    const int flags = sf->flags;
+    CILK_ASSERT(flags & CILK_FRAME_SUSPENDED);
+    CILK_ASSERT(!sf->call_parent);
+    CILK_ASSERT(w->head == w->tail);
+
+    /* A frame can not be resumed unless it was suspended. */
+    CILK_ASSERT(ff->sync_sp != NULL);
+
+    /* The leftmost frame has no allocated stack */
+    if (ff->simulated_stolen)
+        CILK_ASSERT(flags & CILK_FRAME_UNSYNCHED);
+    else if (flags & CILK_FRAME_UNSYNCHED)
+        /* XXX By coincidence sync_sp could be null. */
+        CILK_ASSERT(ff->fiber_self != NULL);
+    else
+        /* XXX This frame could be resumed unsynched on the leftmost stack */
+        CILK_ASSERT((ff->sync_master == 0 || ff->sync_master == w));
+    CILK_ASSERT(w->l->frame_ff == ff);
+#endif    
+}
+
+
+/**
+ * This method is the first method that should execute after we've
+ * switched to a scheduling fiber from user code.
+ *
+ * @param fiber The scheduling fiber for the current worker.
+ * @param wptr  The current worker.
+ */
+static void enter_runtime_transition_proc(cilk_fiber *fiber)
+{
+    // We can execute this method for one of three reasons:
+    // 1. Undo-detach finds parent stolen.
+    // 2. Sync suspends frame.
+    // 3. Return from Cilk entry point.
+    //
+    //
+    // In cases 1 and 2, the frame may be truly suspended or
+    // may be immediately executed by this worker after provably_good_steal.
+    //
+    // 
+    // There is a fourth case, which can, but does not need to execute
+    // this function:
+    //   4. Starting up the scheduling loop on a user or
+    //      system worker.  In this case, we won't have
+    //      a scheduling stack function to run.
+    __cilkrts_worker* w = cilk_fiber_get_owner(fiber);
+    if (w->l->post_suspend) {
+        // Run the continuation function passed to longjmp_into_runtime
+        run_scheduling_stack_fcn(w);
+
+        // After we have jumped into the runtime and run the
+        // scheduling function, any reducer map the worker had before entering the runtime
+        // should have already been saved into the appropriate full
+        // frame.
+        CILK_ASSERT(NULL == w->reducer_map);
+
+        // There shouldn't be any uncaught exceptions.
+        //
+        // In Windows, the OS catches any exceptions not caught by the
+        // user code.  Thus, we are omitting the check on Windows.
+        //
+        // On Android, calling std::uncaught_exception with the stlport
+        // library causes a seg fault.  Since we're not supporting
+        // exceptions there at this point, just don't do the check
+        //
+        // TBD: Is this check also safe to do on Windows? 
+        CILKBUG_ASSERT_NO_UNCAUGHT_EXCEPTION();
+    }
+}
+
+
+/**
+ * Method called to jump back to executing user code.
+ *
+ * A normal return from the runtime back to resuming user code calls
+ * this method.  A computation executed using force_reduce also calls
+ * this method to return to user code.
+ *
+ * This function should not contain any code that depends on a fiber.
+ * In a force-reduce case, the user worker may not have a fiber.  In
+ * the force-reduce case, we call this method directly instead of
+ * calling @c user_code_resume_after_switch_into_runtime.
+ */
+static inline NORETURN
+cilkrts_resume(__cilkrts_stack_frame *sf, full_frame *ff)
+{
+    // Save the sync stack pointer, and do the bookkeeping
+    char* sync_sp = ff->sync_sp;
+    __cilkrts_take_stack(ff, sync_sp);  // leaves ff->sync_sp null
+
+    sf->flags &= ~CILK_FRAME_SUSPENDED;
+    // Actually longjmp to the user code.
+    // We may have exceptions to deal with, since we are resuming
+    // a previous-suspended frame.
+    sysdep_longjmp_to_sf(sync_sp, sf, ff);
+}
+
+
+/**
+ * Called by the user-code fiber right before resuming a full frame
+ * (sf/ff).
+ *
+ * This method pulls sf/ff out of the worker, and then calls
+ * cilkrts_resume to jump to user code.
+ */
+static NORETURN
+user_code_resume_after_switch_into_runtime(cilk_fiber *fiber)
+{
+    __cilkrts_worker *w = cilk_fiber_get_owner(fiber);
+    __cilkrts_stack_frame *sf;
+    full_frame *ff;
+    sf = w->current_stack_frame;
+    ff = sf->worker->l->frame_ff;
+
+#if FIBER_DEBUG >= 1    
+    CILK_ASSERT(ff->fiber_self == fiber);
+    cilk_fiber_data *fdata = cilk_fiber_get_data(fiber);
+    DBGPRINTF ("%d-%p: resume_after_switch_into_runtime, fiber=%p\n",
+               w->self, w, fiber);
+    CILK_ASSERT(sf == fdata->resume_sf);
+#endif
+
+    // Notify the Intel tools that we're stealing code
+    ITT_SYNC_ACQUIRED(sf->worker);
+    NOTIFY_ZC_INTRINSIC("cilk_continue", sf);
+    cilk_fiber_invoke_tbb_stack_op(fiber, CILK_TBB_STACK_ADOPT);
+
+    // Actually jump to user code.
+    cilkrts_resume(sf, ff);
+ }
+
+
+/* The current stack is about to either be suspended or destroyed.  This
+ * function will switch to the stack on which the scheduler is suspended and
+ * resume running the scheduler within function do_work().  Upon waking up,
+ * the scheduler will run the 'cont' function, using the supplied worker and
+ * frame.
+ */
+static NORETURN
+longjmp_into_runtime(__cilkrts_worker *w,
+                     scheduling_stack_fcn_t fcn,
+                     __cilkrts_stack_frame *sf)
+{
+    full_frame *ff, *ff2;
+
+    CILK_ASSERT(!w->l->post_suspend);
+    ff = w->l->frame_ff;
+
+    // If we've got only one worker, stealing shouldn't be possible.
+    // Assume that this is a steal or return from spawn in a force-reduce case.
+    // We don't have a scheduling stack to switch to, so call the continuation
+    // function directly.
+    if (1 == w->g->P) {
+        fcn(w, ff, sf);
+
+        /* The call to function c() will have pushed ff as the next frame.  If
+         * this were a normal (non-forced-reduce) execution, there would have
+         * been a pop_next_frame call in a separate part of the runtime.  We
+         * must call pop_next_frame here to complete the push/pop cycle. */
+        ff2 = pop_next_frame(w);
+
+        setup_for_execution(w, ff2, 0);
+        scheduling_fiber_prepare_to_resume_user_code(w, ff2, w->current_stack_frame);
+        cilkrts_resume(w->current_stack_frame, ff2);
+        
+// Suppress clang warning that the expression result is unused
+#if defined(__clang__) && (! defined(__INTEL_COMPILER))
+#   pragma clang diagnostic push
+#   pragma clang diagnostic ignored "-Wunused-value"
+#endif // __clang__
+        /* no return */
+        CILK_ASSERT(((void)"returned from __cilkrts_resume", 0));
+#if defined(__clang__) && (! defined(__INTEL_COMPILER))
+#   pragma clang diagnostic pop
+#endif // __clang__
+    }
+
+    w->l->post_suspend = fcn;
+    w->l->suspended_stack = sf;
+
+    ITT_SYNC_RELEASING(w);
+    ITT_SYNC_PREPARE(w);
+
+#if FIBER_DEBUG >= 2
+    fprintf(stderr, "ThreadId=%p, W=%d: about to switch into runtime... w->l->frame_ff = %p, sf=%p\n",
+            cilkos_get_current_thread_id(),
+            w->self, w->l->frame_ff,
+            sf);
+#endif
+
+    // Current fiber is either the (1) one we are about to free,
+    // or (2) it has been passed up to the parent.
+    cilk_fiber *current_fiber = ( w->l->fiber_to_free ?
+                                  w->l->fiber_to_free :
+                                  w->l->frame_ff->parent->fiber_child );
+    cilk_fiber_data* fdata = cilk_fiber_get_data(current_fiber);
+    CILK_ASSERT(NULL == w->l->frame_ff->fiber_self);
+
+    // Clear the sf in the current fiber for cleanliness, to prevent
+    // us from accidentally resuming a bad sf.
+    // Technically, resume_sf gets overwritten for a fiber when
+    // we are about to resume it anyway.
+    fdata->resume_sf = NULL;
+    CILK_ASSERT(fdata->owner == w);
+
+    // Set the function to execute immediately after switching to the
+    // scheduling fiber, but before freeing any fibers.
+    cilk_fiber_set_post_switch_proc(w->l->scheduling_fiber,
+                                    enter_runtime_transition_proc);
+    cilk_fiber_invoke_tbb_stack_op(current_fiber, CILK_TBB_STACK_ORPHAN);
+    
+    if (w->l->fiber_to_free) {
+        // Case 1: we are freeing this fiber.  We never
+        // resume this fiber again after jumping into the runtime.
+        w->l->fiber_to_free = NULL;
+
+        // Extra check. Normally, the fiber we are about to switch to
+        // should have a NULL owner.
+        CILK_ASSERT(NULL == cilk_fiber_get_data(w->l->scheduling_fiber)->owner);
+#if FIBER_DEBUG >= 4
+        fprintf(stderr, "ThreadId=%p, W=%d: about to switch into runtime.. current_fiber = %p, deallcoate, switch to fiber %p\n",
+                cilkos_get_current_thread_id(),
+                w->self,
+                current_fiber, w->l->scheduling_fiber);
+#endif
+        cilk_fiber_invoke_tbb_stack_op(current_fiber, CILK_TBB_STACK_RELEASE);
+        NOTE_INTERVAL(w, INTERVAL_DEALLOCATE_RESUME_OTHER);
+        cilk_fiber_remove_reference_from_self_and_resume_other(current_fiber,
+                                                               &w->l->fiber_pool,
+                                                               w->l->scheduling_fiber);
+        // We should never come back here!
+        CILK_ASSERT(0);
+    }
+    else {        
+        // Case 2: We are passing the fiber to our parent because we
+        // are leftmost.  We should come back later to
+        // resume execution of user code.
+        //
+        // If we are not freeing a fiber, there we must be
+        // returning from a spawn or processing an exception.  The
+        // "sync" path always frees a fiber.
+        // 
+        // We must be the leftmost child, and by left holder logic, we
+        // have already moved the current fiber into our parent full
+        // frame.
+#if FIBER_DEBUG >= 2
+        fprintf(stderr, "ThreadId=%p, W=%d: about to suspend self into runtime.. current_fiber = %p, deallcoate, switch to fiber %p\n",
+                cilkos_get_current_thread_id(),
+                w->self,
+                current_fiber, w->l->scheduling_fiber);
+#endif
+
+        NOTE_INTERVAL(w, INTERVAL_SUSPEND_RESUME_OTHER);
+
+        cilk_fiber_suspend_self_and_resume_other(current_fiber,
+                                                 w->l->scheduling_fiber);
+        // Resuming this fiber returns control back to
+        // this function because our implementation uses OS fibers.
+        //
+        // On Unix, we could have the choice of passing the
+        // user_code_resume_after_switch_into_runtime as an extra "resume_proc"
+        // that resumes execution of user code instead of the
+        // jumping back here, and then jumping back to user code.
+#if FIBER_DEBUG >= 2
+        CILK_ASSERT(fdata->owner == __cilkrts_get_tls_worker());
+#endif
+        user_code_resume_after_switch_into_runtime(current_fiber);
+    }
+}
+
+/*
+ * Send a message to the children of the specified worker: run or wait.
+ */
+static void notify_children(__cilkrts_worker *w, unsigned int msg)
+{
+    int child_num;
+    __cilkrts_worker *child;
+    int num_sys_workers = w->g->P - 1;
+
+    // If worker is "n", then its children are 2n + 1, and 2n + 2.
+    child_num = (w->self << 1) + 1;
+    if (child_num < num_sys_workers) {
+        child = w->g->workers[child_num];
+        CILK_ASSERT(child->l->signal_node);
+        signal_node_msg(child->l->signal_node, msg);
+        child_num++;
+        if (child_num < num_sys_workers) {
+            child = w->g->workers[child_num];
+            CILK_ASSERT(child->l->signal_node);
+            signal_node_msg(child->l->signal_node, msg);
+        }
+    }
+}
+
+/*
+ * Notify this worker's children that they need to wait.
+ */
+static void notify_children_wait(__cilkrts_worker *w)
+{
+    notify_children(w, 0);
+}
+
+/*
+ * Notify this worker's children to run and start trying to steal.
+ */
+static void notify_children_run(__cilkrts_worker *w)
+{
+    notify_children(w, 1);
+}
+
+/**
+ * A single "check" to find work, either on our queue or through a
+ * steal attempt.  This method checks our local queue once, and
+ * performs one steal attempt.
+ */
+static full_frame* check_for_work(__cilkrts_worker *w)
+{
+    full_frame *ff = NULL;
+    ff = pop_next_frame(w);
+    // If there is no work on the queue, try to steal some.
+    if (NULL == ff) {
+        START_INTERVAL(w, INTERVAL_STEALING) {
+            if (w->l->type != WORKER_USER && w->l->team != NULL) {
+                // At this point, the worker knows for certain that it has run
+                // out of work.  Therefore, it loses its team affiliation.  User
+                // workers never change teams, of course.
+                __cilkrts_worker_lock(w);
+                w->l->team = NULL;
+                __cilkrts_worker_unlock(w);
+            }
+
+            // If we are about to do a random steal, we should have no
+            // full frame...
+            CILK_ASSERT(NULL == w->l->frame_ff);
+            random_steal(w);
+        } STOP_INTERVAL(w, INTERVAL_STEALING);
+
+        // If the steal was successful, then the worker has populated its next
+        // frame with the work to resume.
+        ff = pop_next_frame(w);
+        if (NULL == ff) {
+            // Punish the worker for failing to steal.
+            // No quantum for you!
+            __cilkrts_yield();
+            w->l->steal_failure_count++;
+        } else {
+            // Reset steal_failure_count since there is obviously still work to
+            // be done.
+            w->l->steal_failure_count = 0;
+        }
+    }
+    return ff;
+}
+
+/**
+ * Keep stealing or looking on our queue.
+ *
+ * Returns either when a full frame is found, or NULL if the
+ * computation is done.
+ */ 
+static full_frame* search_until_work_found_or_done(__cilkrts_worker *w)
+{
+    full_frame *ff = NULL;
+    // Find a full frame to execute (either through random stealing,
+    // or because we pull it off w's 1-element queue).
+    while (!ff) {
+        // Check worker state to figure out our next action.
+        switch (worker_runnable(w))    
+        {
+        case SCHEDULE_RUN:             // One attempt at checking for work.
+            ff = check_for_work(w);
+            break;
+        case SCHEDULE_WAIT:            // go into wait-mode.
+            CILK_ASSERT(WORKER_SYSTEM == w->l->type);
+            // If we are about to wait, then we better not have
+            // a frame that we should execute...
+            CILK_ASSERT(NULL == w->l->next_frame_ff);
+            notify_children_wait(w);
+            signal_node_wait(w->l->signal_node);
+            // ...
+            // Runtime is waking up.
+            notify_children_run(w);
+            w->l->steal_failure_count = 0;
+            break;
+        case SCHEDULE_EXIT:            // exit the scheduler.
+            CILK_ASSERT(WORKER_USER != w->l->type);
+            return NULL;
+        default:
+            CILK_ASSERT(0);
+            abort();
+        }
+    }
+    return ff;
+}
+
+/**
+ * The proc method for a scheduling fiber on a user worker.
+ * 
+ * When a user worker jumps into the runtime, it jumps into this
+ * method by either starting it if the scheduling fiber has never run
+ * before, or resuming the fiber if it was previously suspended.
+ */
+COMMON_PORTABLE
+void scheduler_fiber_proc_for_user_worker(cilk_fiber *fiber)
+{
+    __cilkrts_worker* w = cilk_fiber_get_owner(fiber);
+    CILK_ASSERT(w);
+
+    // This must be a user worker
+    CILK_ASSERT(WORKER_USER == w->l->type);
+
+    // If we aren't the current worker, then something is very wrong
+    // here..
+    verify_current_wkr(w);
+
+    __cilkrts_run_scheduler_with_exceptions(w);
+}
+
+
+/**
+ * The body of the runtime scheduling loop.  This function executes in
+ * 4 stages:
+ *
+ * 1. Transitions from the user code into the runtime by
+ *    executing any scheduling-stack functions.
+ * 2. Looks for a full frame enqueued from a successful provably
+ *    good steal.
+ * 3. If no full frame is found in step 2, steal until
+ *    a frame is found or we are done.  If we are done, finish
+ *    the scheduling loop. 
+ * 4. When a frame is found, setup to resume user code.
+ *    In particular, suspend the current fiber and resume the
+ *    user fiber to execute the frame.
+ *
+ * Returns a fiber object that we should switch to after completing
+ * the body of the loop, or NULL if we should continue executing on
+ * this fiber.
+ *
+ * @pre @c current_fiber should equal @c wptr->l->scheduling_fiber
+ * 
+ * @param current_fiber   The currently executing (scheduling_ fiber
+ * @param wptr            The currently executing worker.
+ * @param return          The next fiber we should switch to.
+ */
+static cilk_fiber* worker_scheduling_loop_body(cilk_fiber* current_fiber,
+                                               void* wptr)
+{
+    __cilkrts_worker *w = (__cilkrts_worker*) wptr;
+    CILK_ASSERT(current_fiber == w->l->scheduling_fiber);
+
+    // Stage 1: Transition from executing user code to the runtime code.
+    // We don't need to do this call here any more, because 
+    // every switch to the scheduling fiber should make this call
+    // using a post_switch_proc on the fiber.
+    //
+    //  enter_runtime_transition_proc(w->l->scheduling_fiber, wptr);
+
+    // After Stage 1 is complete, w should no longer have
+    // an associated full frame.
+    CILK_ASSERT(NULL == w->l->frame_ff);
+
+    // Stage 2.  First do a quick check of our 1-element queue.
+    full_frame *ff = pop_next_frame(w);
+
+    if (!ff) {
+        // Stage 3.  We didn't find anything from our 1-element
+        // queue.  Now go through the steal loop to find work. 
+        ff = search_until_work_found_or_done(w);
+        if (!ff) {
+            CILK_ASSERT(w->g->work_done);
+            return NULL;
+        }
+    }
+
+    // Stage 4.  Now that we have found a full frame to work on,
+    // actually execute it.
+    __cilkrts_stack_frame *sf;
+
+    // There shouldn't be any uncaught exceptions.
+    //
+    // In Windows, the OS catches any exceptions not caught by the
+    // user code.  Thus, we are omitting the check on Windows.
+    //
+    // On Android, calling std::uncaught_exception with the stlport
+    // library causes a seg fault.  Since we're not supporting
+    // exceptions there at this point, just don't do the check
+    CILKBUG_ASSERT_NO_UNCAUGHT_EXCEPTION();
+
+    BEGIN_WITH_WORKER_LOCK(w) {
+        CILK_ASSERT(!w->l->frame_ff);
+        BEGIN_WITH_FRAME_LOCK(w, ff) {
+            sf = ff->call_stack;
+            CILK_ASSERT(sf && !sf->call_parent);
+            setup_for_execution(w, ff, 0);
+        } END_WITH_FRAME_LOCK(w, ff);
+    } END_WITH_WORKER_LOCK(w);
+
+    /* run it */
+    //
+    // Prepare to run the full frame.  To do so, we need to:
+    //   (a) Execute some code on this fiber (the scheduling
+    //       fiber) to set up data structures, and
+    //   (b) Suspend the scheduling fiber, and resume the
+    //       user-code fiber.
+
+    // Part (a). Set up data structures.
+    scheduling_fiber_prepare_to_resume_user_code(w, ff, sf);
+
+    cilk_fiber *other = w->l->frame_ff->fiber_self;
+    cilk_fiber_data* other_data = cilk_fiber_get_data(other);
+    cilk_fiber_data* current_fiber_data = cilk_fiber_get_data(current_fiber);
+
+    // I believe two cases are possible here, both of which
+    // should have other_data->resume_sf as NULL.
+    //
+    // 1. Resuming a fiber that was previously executing
+    //    user code (i.e., a provably-good-steal).
+    //    In this case, resume_sf should have been
+    //    set to NULL when it was suspended.
+    //
+    // 2. Resuming code on a steal.  In this case, since we
+    //    grabbed a new fiber, resume_sf should be NULL.
+    CILK_ASSERT(NULL == other_data->resume_sf);
+        
+#if FIBER_DEBUG >= 2
+    fprintf(stderr, "W=%d: other fiber=%p, setting resume_sf to %p\n",
+            w->self, other, other_data->resume_sf);
+#endif
+    // Update our own fiber's data.
+    current_fiber_data->resume_sf = NULL;
+    // The scheduling fiber should have the right owner from before.
+    CILK_ASSERT(current_fiber_data->owner == w);
+    other_data->resume_sf = sf;
+        
+
+#if FIBER_DEBUG >= 3
+    fprintf(stderr, "ThreadId=%p (about to suspend self resume other), W=%d: current_fiber=%p, other=%p, current_fiber->resume_sf = %p, other->resume_sf = %p\n",
+            cilkos_get_current_thread_id(),
+            w->self,
+            current_fiber, other,
+            current_fiber_data->resume_sf,
+            other_data->resume_sf);
+#endif
+    return other;
+}
+
+
+/**
+ * This function is executed once by each worker, to initialize its
+ * scheduling loop.
+ */
+static void worker_scheduler_init_function(__cilkrts_worker *w)
+{
+    // First, execute the startup tasks that must happen for all
+    // worker types.
+    ITT_SYNC_PREPARE(w);
+    /* Notify tools about the new worker. Inspector needs this, but we
+       don't want to confuse Cilkscreen with system threads.  User threads
+       do this notification in bind_thread */
+    if (! w->g->under_ptool)
+        __cilkrts_cilkscreen_establish_worker(w);
+
+    // Seed the initial random number generator.
+    // If we forget to do this, then the worker always steals from 0.
+    // Programs will still execute correctly, but
+    // you may see a subtle performance bug...
+    mysrand(w, (w->self + 1));
+
+    // The startup work varies, depending on the worker type.
+    switch (w->l->type) {
+    case WORKER_USER:
+        // Stop working once we've entered the scheduler.
+        // For user workers, INTERVAL_IN_SCHEDULER counts the time
+        // since we called bind_thread.
+        break;
+
+    case WORKER_SYSTEM:
+        // If a system worker is starting, we must also be starting
+        // the runtime.
+
+        // Runtime begins in a wait-state and is woken up by the first user
+        // worker when the runtime is ready.
+        signal_node_wait(w->l->signal_node);
+        // ...
+        // Runtime is waking up.
+        notify_children_run(w);
+        w->l->steal_failure_count = 0;
+
+        // For system threads, count all the time this thread is
+        // alive in the scheduling loop.
+        START_INTERVAL(w, INTERVAL_IN_SCHEDULER);
+        START_INTERVAL(w, INTERVAL_WORKING);
+        break;
+    default:
+        __cilkrts_bug("Unknown worker %p of type %d entering scheduling loop\n",
+                      w, w->l->type);
+    }
+}
+
+/**
+ * This function is executed once by each worker, to finish its
+ * scheduling loop.
+ *
+ * @note Currently, only system workers finish their loops.  User
+ * workers will jump away to user code without exiting their
+ * scheduling loop.
+ */ 
+static void worker_scheduler_terminate_function(__cilkrts_worker *w)
+{
+    // A user worker should never finish by falling through the
+    // scheduling loop.
+    CILK_ASSERT(WORKER_USER != w->l->type);
+    STOP_INTERVAL(w, INTERVAL_IN_RUNTIME);
+    STOP_INTERVAL(w, INTERVAL_IN_SCHEDULER);
+}
+
+/**
+ * The main scheduler function executed by a worker's scheduling
+ * fiber.
+ * 
+ * This method is started by either a new system worker, or a user
+ * worker that has stalled and just been imported into the runtime.
+ */
+static void worker_scheduler_function(__cilkrts_worker *w)
+{
+    worker_scheduler_init_function(w);
+
+    // The main scheduling loop body.
+
+    while (!w->g->work_done) {    
+        // Set intervals.  Now we are in the runtime instead of working.
+        START_INTERVAL(w, INTERVAL_IN_RUNTIME);
+        STOP_INTERVAL(w, INTERVAL_WORKING);
+
+        // Execute the "body" of the scheduling loop, and figure
+        // out the fiber to jump to next.
+        cilk_fiber* fiber_to_resume
+            = worker_scheduling_loop_body(w->l->scheduling_fiber, w);
+
+        if (fiber_to_resume) {
+            // Suspend the current fiber and resume next one.
+            NOTE_INTERVAL(w, INTERVAL_SUSPEND_RESUME_OTHER);
+            STOP_INTERVAL(w, INTERVAL_IN_RUNTIME);
+            START_INTERVAL(w, INTERVAL_WORKING);
+            cilk_fiber_suspend_self_and_resume_other(w->l->scheduling_fiber,
+                                                     fiber_to_resume);
+
+            // Return here only when this (scheduling) fiber is
+            // resumed (i.e., this worker wants to reenter the runtime).
+        }
+    }
+
+    // Finish the scheduling loop.
+    worker_scheduler_terminate_function(w);
+}
+
+
+/*************************************************************
+  Forward declarations for reduction protocol.
+*************************************************************/
+
+static __cilkrts_worker*
+execute_reductions_for_sync(__cilkrts_worker *w,
+                            full_frame *ff,
+                            __cilkrts_stack_frame *sf_at_sync);
+
+static __cilkrts_worker*
+execute_reductions_for_spawn_return(__cilkrts_worker *w,
+                                    full_frame *ff,
+                                    __cilkrts_stack_frame *returning_sf);
+
+                                                             
+
+/*************************************************************
+  Scheduler functions that are callable by client code
+*************************************************************/
+static full_frame *disown(__cilkrts_worker *w,
+                          full_frame *ff,
+                          __cilkrts_stack_frame *sf,
+                          const char *why)
+{
+    CILK_ASSERT(ff);
+    make_unrunnable(w, ff, sf, sf != 0, why);
+    w->l->frame_ff = 0;
+    return ff->parent;
+}
+
+/**
+ * Called when ff is returning from a spawn, and we need to execute a
+ * reduction.
+ *
+ * @param w             The currently executing worker.
+ * @param ff            The full frame for w.
+ * @param returning_sf  The stack frame for the spawn helper that is returning.
+ *
+ * Normally, by the time we gain control in the runtime, the worker
+ * has already popped off the __cilkrts_stack_frame "returning_sf"
+ * from its call chain.
+ * 
+ * When we have only serial reductions, w->current_stack_frame is not
+ * needed any more, because w is about to enter the runtime scheduling
+ * loop anyway.  Similarly, the frame "ff" is slated to be destroyed
+ * after the runtime finishes the return from spawn and splices ff out
+ * of the tree of full frames.
+ *
+ * To execute a parallel reduction, however, we still want
+ * w->current_stack_frame == returning_sf, and we are going to use the
+ * frame ff for a little bit longer.
+ *
+ * This method:
+ *
+ *   1. Puts returning_sf back as w's current stack frame.
+ *   2. Makes "ff" runnable again on w.
+ */ 
+static inline
+void restore_frame_for_spawn_return_reduction(__cilkrts_worker *w,
+                                              full_frame *ff,
+                                              __cilkrts_stack_frame *returning_sf) {
+#if REDPAR_DEBUG >= 2
+    CILK_ASSERT(returning_sf);
+    CILK_ASSERT(returning_sf->worker == w);
+#endif
+    // Change w's current stack frame back to "returning_sf".
+    //
+    // Intuitively, w->current_stack_frame should be
+    // returning_sf->call_parent at this point.
+    //
+    // We can not assert this, however, because the pop of
+    // returning_sf from the call chain has already cleared
+    // returning_sf->call_parent.  We don't want to restore the call
+    // parent of returning_sf, because its parent has been stolen, and
+    // the runtime assumes that steals break this link.
+
+    // We cannot assert call_parent is NULL either, since that's not true for
+    // Win64 exception handling
+//    CILK_ASSERT(returning_sf->call_parent == NULL);
+    w->current_stack_frame = returning_sf;
+
+    // Make the full frame "ff" runnable again, in preparation for
+    // executing the reduction.
+    make_runnable(w, ff);
+}
+
+
+NORETURN __cilkrts_c_sync(__cilkrts_worker *w,
+                          __cilkrts_stack_frame *sf_at_sync)
+{
+    full_frame *ff; 
+
+    // Claim: This read of w->l->frame_ff can occur without
+    // holding the worker lock because when w has reached a sync
+    // and entered the runtime (because it stalls), w's deque is empty
+    // and no one else can steal and change w->l->frame_ff.
+
+    ff = w->l->frame_ff;
+#ifdef _WIN32
+    __cilkrts_save_exception_state(w, ff);
+#else
+    // Move any pending exceptions into the full frame
+    CILK_ASSERT(NULL == ff->pending_exception);
+    ff->pending_exception = w->l->pending_exception;
+    w->l->pending_exception = NULL;
+#endif
+    
+    w = execute_reductions_for_sync(w, ff, sf_at_sync);
+
+#if FIBER_DEBUG >= 3
+    fprintf(stderr, "ThreadId=%p, w->self = %d. about to longjmp_into_runtim[c_sync] with ff=%p\n",
+            cilkos_get_current_thread_id(), w->self, ff);
+#endif    
+
+    longjmp_into_runtime(w, do_sync, sf_at_sync);
+}
+
+static void do_sync(__cilkrts_worker *w, full_frame *ff,
+                    __cilkrts_stack_frame *sf)
+{
+    //int abandoned = 1;
+    enum provably_good_steal_t steal_result = ABANDON_EXECUTION;
+
+    START_INTERVAL(w, INTERVAL_SYNC_CHECK) {
+        BEGIN_WITH_WORKER_LOCK_OPTIONAL(w) {
+
+            CILK_ASSERT(ff);
+            BEGIN_WITH_FRAME_LOCK(w, ff) {
+                CILK_ASSERT(sf->call_parent == 0);
+                CILK_ASSERT(sf->flags & CILK_FRAME_UNSYNCHED);
+
+                // Before switching into the scheduling fiber, we should have
+                // already taken care of deallocating the current
+                // fiber. 
+                CILK_ASSERT(NULL == ff->fiber_self);
+
+                // Update the frame's pedigree information if this is an ABI 1
+                // or later frame
+                if (CILK_FRAME_VERSION_VALUE(sf->flags) >= 1)
+                {
+                    sf->parent_pedigree.rank = w->pedigree.rank;
+                    sf->parent_pedigree.parent = w->pedigree.parent;
+
+                    // Note that the pedigree rank needs to be updated
+                    // when setup_for_execution_pedigree runs
+                    sf->flags |= CILK_FRAME_SF_PEDIGREE_UNSYNCHED;
+                }
+
+                /* the decjoin() occurs in provably_good_steal() */
+                steal_result = provably_good_steal(w, ff);
+
+            } END_WITH_FRAME_LOCK(w, ff);
+            // set w->l->frame_ff = NULL after checking abandoned
+            if (WAIT_FOR_CONTINUE != steal_result) {
+                w->l->frame_ff = NULL;
+            }
+        } END_WITH_WORKER_LOCK_OPTIONAL(w);
+    } STOP_INTERVAL(w, INTERVAL_SYNC_CHECK);
+
+    // Now, if we are in a replay situation and provably_good_steal() returned
+    // WAIT_FOR_CONTINUE, we should sleep, reacquire locks, call
+    // provably_good_steal(), and release locks until we get a value other
+    // than WAIT_FOR_CONTINUE from the function.
+#ifdef CILK_RECORD_REPLAY
+    // We don't have to explicitly check for REPLAY_LOG below because
+    // steal_result can only be set to WAIT_FOR_CONTINUE during replay
+    while(WAIT_FOR_CONTINUE == steal_result)
+    {
+        __cilkrts_sleep();
+        BEGIN_WITH_WORKER_LOCK_OPTIONAL(w)
+        {
+            ff = w->l->frame_ff;
+            BEGIN_WITH_FRAME_LOCK(w, ff)
+            {
+                steal_result = provably_good_steal(w, ff);
+            } END_WITH_FRAME_LOCK(w, ff);
+            if (WAIT_FOR_CONTINUE != steal_result)
+                w->l->frame_ff = NULL;
+        } END_WITH_WORKER_LOCK_OPTIONAL(w);
+    }
+#endif  // CILK_RECORD_REPLAY
+
+#ifdef ENABLE_NOTIFY_ZC_INTRINSIC
+    // If we can't make any further progress on this thread, tell Inspector
+    // that we're abandoning the work and will go find something else to do.
+    if (ABANDON_EXECUTION == steal_result)
+    {
+        NOTIFY_ZC_INTRINSIC("cilk_sync_abandon", 0);
+    }
+#endif // defined ENABLE_NOTIFY_ZC_INTRINSIC
+
+    return; /* back to scheduler loop */
+}
+
+/* worker W completely promotes its own deque, simulating the case
+   where the whole deque is stolen.  We use this mechanism to force
+   the allocation of new storage for reducers for race-detection
+   purposes. */
+void __cilkrts_promote_own_deque(__cilkrts_worker *w)
+{
+    // Remember the fiber we start this method on.
+    CILK_ASSERT(w->l->frame_ff);
+    cilk_fiber* starting_fiber = w->l->frame_ff->fiber_self;
+    
+    BEGIN_WITH_WORKER_LOCK(w) {
+        while (dekker_protocol(w)) {
+            /* PLACEHOLDER_FIBER is used as non-null marker to tell detach()
+               and make_child() that this frame should be treated as a spawn
+               parent, even though we have not assigned it a stack. */
+            detach_for_steal(w, w, PLACEHOLDER_FIBER);
+        }
+    } END_WITH_WORKER_LOCK(w);
+
+
+    // TBD: The management of full frames and fibers is a bit
+    // sketchy here.  We are promoting stack frames into full frames,
+    // and pretending they are stolen away, but no other worker is
+    // actually working on them.  Some runtime invariants
+    // may be broken here.
+    //
+    // Technically, if we are simulating a steal from w
+    // w should get a new full frame, but
+    // keep the same fiber.  A real thief would be taking the
+    // loot frame away, get a new fiber, and starting executing the
+    // loot frame.
+    //
+    // What should a fake thief do?  Where does the frame go? 
+
+    // In any case, we should be finishing the promotion process with
+    // the same fiber with.
+    CILK_ASSERT(w->l->frame_ff);
+    CILK_ASSERT(w->l->frame_ff->fiber_self == starting_fiber);
+}
+
+
+
+/* the client code calls this function after a spawn when the dekker
+   protocol fails.  The function may either return or longjmp
+   into the rts
+
+   This function takes in a "returning_sf" argument which corresponds
+   to the __cilkrts_stack_frame that we are finishing (i.e., the
+   argument to __cilkrts_leave_frame).
+   */
+void __cilkrts_c_THE_exception_check(__cilkrts_worker *w, 
+                                     __cilkrts_stack_frame *returning_sf)
+{
+    full_frame *ff;
+    int stolen_p;
+    __cilkrts_stack_frame *saved_sf = NULL;
+
+    START_INTERVAL(w, INTERVAL_THE_EXCEPTION_CHECK);
+
+    BEGIN_WITH_WORKER_LOCK(w) {
+        ff = w->l->frame_ff;
+        CILK_ASSERT(ff);
+        /* This code is called only upon a normal return and never
+           upon an exceptional return.  Assert that this is the
+           case. */
+        CILK_ASSERT(!w->l->pending_exception);
+
+        reset_THE_exception(w);
+        stolen_p = !(w->head < (w->tail + 1)); /* +1 because tail was
+                                                  speculatively
+                                                  decremented by the
+                                                  compiled code */
+
+        if (stolen_p) {
+            /* XXX This will be charged to THE for accounting purposes */
+            __cilkrts_save_exception_state(w, ff);
+
+            // Save the value of the current stack frame.
+            saved_sf = w->current_stack_frame;
+
+            // Reverse the decrement from undo_detach.
+            // This update effectively resets the deque to be
+            // empty (i.e., changes w->tail back to equal w->head). 
+            // We need to reset the deque to execute parallel
+            // reductions.  When we have only serial reductions, it
+            // does not matter, since serial reductions do not
+            // change the deque.
+            w->tail++;
+#if REDPAR_DEBUG > 1            
+            // ASSERT our deque is empty.
+            CILK_ASSERT(w->head == w->tail);
+#endif
+        }
+    } END_WITH_WORKER_LOCK(w);
+
+    STOP_INTERVAL(w, INTERVAL_THE_EXCEPTION_CHECK);
+
+    if (stolen_p)
+    {
+        w = execute_reductions_for_spawn_return(w, ff, returning_sf);
+
+        // "Mr. Policeman?  My parent always told me that if I was in trouble
+        // I should ask a nice policeman for help.  I can't find my parent
+        // anywhere..."
+        //
+        // Write a record to the replay log for an attempt to return to a stolen parent
+        replay_record_orphaned(w);
+
+        // Update the pedigree only after we've finished the
+        // reductions.
+        update_pedigree_on_leave_frame(w, returning_sf);
+
+        // Notify Inspector that the parent has been stolen and we're
+        // going to abandon this work and go do something else.  This
+        // will match the cilk_leave_begin in the compiled code
+        NOTIFY_ZC_INTRINSIC("cilk_leave_stolen", saved_sf);
+
+        DBGPRINTF ("%d: longjmp_into_runtime from __cilkrts_c_THE_exception_check\n", w->self);
+        longjmp_into_runtime(w, do_return_from_spawn, 0);
+        DBGPRINTF ("%d: returned from longjmp_into_runtime from __cilkrts_c_THE_exception_check?!\n", w->self);
+    }
+    else
+    {
+        NOTE_INTERVAL(w, INTERVAL_THE_EXCEPTION_CHECK_USELESS);
+        return;
+    }
+}
+
+/* Return an exception to a stolen parent. */
+NORETURN __cilkrts_exception_from_spawn(__cilkrts_worker *w,
+                                        __cilkrts_stack_frame *returning_sf) 
+{
+    full_frame *ff = w->l->frame_ff;
+    // This is almost the same as THE_exception_check, except
+    // the detach didn't happen, we don't need to undo the tail
+    // update.
+    CILK_ASSERT(w->head == w->tail);
+    w = execute_reductions_for_spawn_return(w, ff, returning_sf);
+
+    longjmp_into_runtime(w, do_return_from_spawn, 0);
+    CILK_ASSERT(0);
+}
+
+static void do_return_from_spawn(__cilkrts_worker *w,
+                                 full_frame *ff,
+                                 __cilkrts_stack_frame *sf)
+{
+    full_frame *parent_ff;
+    enum provably_good_steal_t steal_result = ABANDON_EXECUTION;
+
+    BEGIN_WITH_WORKER_LOCK_OPTIONAL(w) {
+        CILK_ASSERT(ff);
+        CILK_ASSERT(!ff->is_call_child);
+        CILK_ASSERT(sf == NULL);
+        parent_ff = ff->parent;
+    
+        BEGIN_WITH_FRAME_LOCK(w, ff) {
+            decjoin(ff);
+        } END_WITH_FRAME_LOCK(w, ff);
+
+        BEGIN_WITH_FRAME_LOCK(w, parent_ff) {
+            if (parent_ff->simulated_stolen)
+                unconditional_steal(w, parent_ff);
+            else
+                steal_result = provably_good_steal(w, parent_ff);
+        } END_WITH_FRAME_LOCK(w, parent_ff);
+
+    } END_WITH_WORKER_LOCK_OPTIONAL(w);
+
+    // Loop here in replay mode
+#ifdef CILK_RECORD_REPLAY
+    // We don't have to explicitly check for REPLAY_LOG below because
+    // steal_result can only get set to WAIT_FOR_CONTINUE during replay.
+    // We also don't have to worry about the simulated_stolen flag
+    // because steal_result can only be set to WAIT_FOR_CONTINUE by
+    // provably_good_steal().
+    while(WAIT_FOR_CONTINUE == steal_result)
+    {
+        __cilkrts_sleep();
+        BEGIN_WITH_WORKER_LOCK_OPTIONAL(w)
+        {
+            BEGIN_WITH_FRAME_LOCK(w, parent_ff)
+            {
+                steal_result = provably_good_steal(w, parent_ff);
+            } END_WITH_FRAME_LOCK(w, parent_ff);
+        } END_WITH_WORKER_LOCK_OPTIONAL(w);
+    }
+#endif  // CILK_RECORD_REPLAY
+
+    // Cleanup the child frame.
+    __cilkrts_destroy_full_frame(w, ff);
+    return;
+}
+
+#ifdef _WIN32
+/* migrate an exception across fibers.  Call this function when an exception has
+ * been thrown and has to traverse across a steal.  The exception has already
+ * been wrapped up, so all that remains is to longjmp() into the continuation,
+ * sync, and re-raise it.
+ */
+void __cilkrts_migrate_exception(__cilkrts_stack_frame *sf) {
+
+    __cilkrts_worker *w = sf->worker;
+    full_frame *ff;
+
+    BEGIN_WITH_WORKER_LOCK(w) {
+        ff = w->l->frame_ff;
+        reset_THE_exception(w);
+        /* there is no need to check for a steal because we wouldn't be here if
+           there weren't a steal. */
+        __cilkrts_save_exception_state(w, ff);
+
+        CILK_ASSERT(w->head == w->tail);
+    } END_WITH_WORKER_LOCK(w);
+
+    {
+        // TBD(jsukha): This function emulates the
+        // the "do_return_from_spawn" path.
+        w = execute_reductions_for_spawn_return(w, ff, sf);
+    }
+
+    longjmp_into_runtime(w, do_return_from_spawn, 0); /* does not return. */
+    CILK_ASSERT(! "Shouldn't be here...");
+}
+#endif
+
+
+/* Pop a call stack from TAIL.  Return the call stack, or NULL if the
+   queue is empty */
+__cilkrts_stack_frame *__cilkrts_pop_tail(__cilkrts_worker *w)
+{
+    __cilkrts_stack_frame *sf;
+    BEGIN_WITH_WORKER_LOCK(w) {
+        __cilkrts_stack_frame *volatile *tail = w->tail;
+        if (w->head < tail) {
+            --tail;
+            sf = *tail;
+            w->tail = tail;
+        } else {
+            sf = 0;
+        }
+    } END_WITH_WORKER_LOCK(w);
+    return sf;
+}
+
+#ifdef CILK_RECORD_REPLAY
+__cilkrts_stack_frame *simulate_pop_tail(__cilkrts_worker *w)
+{
+    __cilkrts_stack_frame *sf;
+    BEGIN_WITH_WORKER_LOCK(w) {
+        if (w->head < w->tail) {
+            sf = *(w->tail-1);
+        } else {
+            sf = 0;
+        }
+    } END_WITH_WORKER_LOCK(w);
+    return sf;
+}
+#endif
+
+
+/* Return from a call, not a spawn. */
+void __cilkrts_return(__cilkrts_worker *w)
+{
+    full_frame *ff, *parent_ff;
+    START_INTERVAL(w, INTERVAL_RETURNING);
+
+    BEGIN_WITH_WORKER_LOCK_OPTIONAL(w) {
+        ff = w->l->frame_ff;
+        CILK_ASSERT(ff);
+        CILK_ASSERT(ff->join_counter == 1);
+        /* This path is not used to return from spawn. */
+        CILK_ASSERT(ff->is_call_child);
+
+        BEGIN_WITH_FRAME_LOCK(w, ff) {
+            // After this call, w->l->frame_ff != ff.
+            // Technically, w will "own" ff until ff is freed,
+            // however, because ff is a dying leaf full frame.
+            parent_ff = disown(w, ff, 0, "return");
+            decjoin(ff);
+
+#ifdef _WIN32
+            __cilkrts_save_exception_state(w, ff);
+#else
+            // Move the pending exceptions into the full frame
+            // This should always be NULL if this isn't a
+            // return with an exception
+            CILK_ASSERT(NULL == ff->pending_exception);
+            ff->pending_exception = w->l->pending_exception;
+            w->l->pending_exception = NULL;
+#endif  // _WIN32
+
+        } END_WITH_FRAME_LOCK(w, ff);
+
+        __cilkrts_fence(); /* redundant */
+
+        CILK_ASSERT(parent_ff);
+
+        BEGIN_WITH_FRAME_LOCK(w, parent_ff) {
+            finalize_child_for_call(w, parent_ff, ff);
+        } END_WITH_FRAME_LOCK(w, parent_ff);
+
+        ff = pop_next_frame(w);
+        /* ff will be non-null except when the parent frame is owned
+           by another worker.
+           CILK_ASSERT(ff)
+        */
+        CILK_ASSERT(!w->l->frame_ff);
+        if (ff) {
+            BEGIN_WITH_FRAME_LOCK(w, ff) {
+                __cilkrts_stack_frame *sf = ff->call_stack;
+                CILK_ASSERT(sf && !sf->call_parent);
+                setup_for_execution(w, ff, 1);
+            } END_WITH_FRAME_LOCK(w, ff);
+        }
+    } END_WITH_WORKER_LOCK_OPTIONAL(w);
+
+    STOP_INTERVAL(w, INTERVAL_RETURNING);
+}
+
+static void __cilkrts_unbind_thread()
+{
+    int stop_cilkscreen = 0;
+    global_state_t *g;
+
+    // Take out the global OS mutex to protect accesses to the table of workers
+    global_os_mutex_lock();
+
+    if (cilkg_is_published()) {
+        __cilkrts_worker *w = __cilkrts_get_tls_worker();
+        if (w) {
+            g = w->g;
+
+            // If there's only 1 worker, the counts will be stopped in
+            // __cilkrts_scheduler
+            if (g->P > 1)
+            {
+                STOP_INTERVAL(w, INTERVAL_WORKING);
+                STOP_INTERVAL(w, INTERVAL_IN_SCHEDULER);
+            }
+
+            __cilkrts_set_tls_worker(0);
+
+            if (w->self == -1) {
+                // This worker is an overflow worker.  I.e., it was created on-
+                // demand when the global pool ran out of workers.
+                destroy_worker(w);
+                __cilkrts_free(w);
+            } else {
+                // This is a normal user worker and needs to be counted by the
+                // global state for the purposes of throttling system workers.
+                w->l->type = WORKER_FREE;
+                __cilkrts_leave_cilk(g);
+            }
+
+            stop_cilkscreen = (0 == g->Q);
+        }
+    }
+    global_os_mutex_unlock();
+
+    /* Turn off Cilkscreen.  This needs to be done when we are NOT holding the
+     * os mutex. */
+    if (stop_cilkscreen)
+        __cilkrts_cilkscreen_disable_instrumentation();
+}
+
+/* special return from the initial frame */
+
+void __cilkrts_c_return_from_initial(__cilkrts_worker *w)
+{
+    struct cilkred_map *rm;
+
+    /* This is only called on a user thread worker. */
+    CILK_ASSERT(w->l->type == WORKER_USER);
+
+    #if REDPAR_DEBUG >= 3
+    fprintf(stderr, "[W=%d, desc=cilkrts_c_return_from_initial, ff=%p]\n",
+            w->self, w->l->frame_ff);
+    #endif
+    
+    BEGIN_WITH_WORKER_LOCK_OPTIONAL(w) {
+        full_frame *ff = w->l->frame_ff;
+        CILK_ASSERT(ff);
+        CILK_ASSERT(ff->join_counter == 1);
+        w->l->frame_ff = 0;
+
+        CILK_ASSERT(ff->fiber_self);
+        // Save any TBB interop data for the next time this thread enters Cilk
+        cilk_fiber_tbb_interop_save_info_from_stack(ff->fiber_self);
+
+        // Deallocate cilk_fiber that mapped to the user stack.  The stack
+        // itself does not get deallocated (of course) but our data
+        // structure becomes divorced from it.
+
+#if FIBER_DEBUG >= 1
+        fprintf(stderr, "ThreadId=%p: w=%d: We are about to deallocate ff->fiber_self  = %p here. w->l->scheduling_fiber = %p. w->l->type = %d\n",
+                cilkos_get_current_thread_id(),
+                w->self,
+                ff->fiber_self,
+                w->l->scheduling_fiber,
+                w->l->type);
+#endif
+        // The fiber in ff is a user-code fiber.  The fiber in
+        // w->l->scheduling_fiber is a scheduling fiber.  These fibers should
+        // never be equal.  When a user worker returns (and will unbind), we
+        // should destroy only the fiber in ff.  The scheduling fiber will be
+        // re-used.
+
+        CILK_ASSERT(ff->fiber_self != w->l->scheduling_fiber);
+
+        START_INTERVAL(w, INTERVAL_FIBER_DEALLOCATE) {
+            // This fiber might not be deallocated here if there
+            // is a pending exception on Windows that refers
+            // to this fiber.
+            //
+            // First "suspend" the fiber, and then try to delete it.
+            cilk_fiber_deallocate_from_thread(ff->fiber_self);
+        } STOP_INTERVAL(w, INTERVAL_FIBER_DEALLOCATE);
+        ff->fiber_self = NULL;
+
+        /* Save reducer map into global_state object */
+        rm = w->reducer_map;
+        w->reducer_map = NULL;
+
+#if REDPAR_DEBUG >= 3
+        fprintf(stderr, "W=%d, reducer_map_to_delete=%p, was in ff=%p\n",
+                w->self,
+                rm,
+                ff);
+#endif
+        __cilkrts_destroy_full_frame(w, ff);
+
+
+        /* Work is never done. w->g->work_done = 1; __cilkrts_fence(); */
+    } END_WITH_WORKER_LOCK_OPTIONAL(w);
+
+
+    save_pedigree_leaf_from_user_worker(w);
+
+    // Workers can have NULL reducer maps now.
+    if (rm) {
+        __cilkrts_destroy_reducer_map(w, rm);
+    }
+
+
+#if FIBER_DEBUG >= 1
+    __cilkrts_worker* tmp = w;
+    int tmp_id = w->self;
+    fprintf(stderr, "w=%d: We are about unbind thread (w= %p)\n",
+            w->self,
+            w);
+#endif
+
+    w = NULL;
+    
+    __cilkrts_unbind_thread();
+
+#if FIBER_DEBUG >= 1
+    
+    fprintf(stderr, "w=%p, %d: Finished unbind\n",
+            tmp, tmp_id);
+#endif
+
+    /* Other workers will stop trying to steal if this was the last worker. */
+
+    return;
+}
+
+
+/*
+ * __cilkrts_restore_stealing
+ *
+ * Restore the protected_tail to a previous state, possibly allowing frames
+ * to be stolen.  The dekker_protocol has been extended to steal only if
+ * head+1 is < protected_tail.
+ */
+
+void __cilkrts_restore_stealing(
+    __cilkrts_worker *w,
+    __cilkrts_stack_frame *volatile *saved_protected_tail)
+{
+    /* On most x86 this pair of operations would be slightly faster
+       as an atomic exchange due to the implicit memory barrier in
+       an atomic instruction. */
+    w->protected_tail = saved_protected_tail;
+    __cilkrts_fence();
+}
+
+/*
+ * __cilkrts_disallow_stealing
+ *
+ * Move the protected_tail to NEW_PROTECTED_TAIL, preventing any
+ * frames from being stolen.  If NEW_PROTECTED_TAIL is NULL, prevent
+ * stealing from the whole queue.  The dekker_protocol has been
+ * extended to only steal if head+1 is also < protected_tail.
+ */
+
+__cilkrts_stack_frame *volatile *__cilkrts_disallow_stealing(
+    __cilkrts_worker *w,
+    __cilkrts_stack_frame *volatile *new_protected_tail)
+{
+    __cilkrts_stack_frame *volatile *saved_protected_tail = w->protected_tail;
+
+    if (!new_protected_tail)
+        new_protected_tail = w->l->ltq;
+
+    if (w->protected_tail > new_protected_tail) {
+        w->protected_tail = new_protected_tail;
+        /* Issue a store-store barrier.  The update to protected_tail
+           here must precede the update to tail in the next spawn.
+           On x86 this is probably not needed. */
+#if defined __GNUC__ && __ICC >= 1200 && !(__MIC__ ||__MIC2__)
+        _mm_sfence();
+#else
+        __cilkrts_fence();
+#endif
+    }
+
+    return saved_protected_tail;
+}
+
+/*************************************************************
+  Initialization and startup 
+*************************************************************/
+
+__cilkrts_worker *make_worker(global_state_t *g,
+                              int self, __cilkrts_worker *w)
+{
+    w->self = self;
+    w->g = g;
+
+    w->pedigree.rank = 0;    // Initial rank is 0
+    w->pedigree.parent = NULL;
+
+    w->l = (local_state *)__cilkrts_malloc(sizeof(*w->l));
+
+    __cilkrts_frame_malloc_per_worker_init(w);
+
+    w->reducer_map = NULL;
+    w->current_stack_frame = NULL;
+    w->reserved = NULL;
+    
+    w->l->worker_magic_0 = WORKER_MAGIC_0;
+    w->l->team = NULL;
+    w->l->type = WORKER_FREE;
+    
+    __cilkrts_mutex_init(&w->l->lock);
+    __cilkrts_mutex_init(&w->l->steal_lock);
+    w->l->do_not_steal = 0;
+    w->l->frame_ff = 0;
+    w->l->next_frame_ff = 0;
+    w->l->last_full_frame = NULL;
+
+    w->l->ltq = (__cilkrts_stack_frame **)
+        __cilkrts_malloc(g->ltqsize * sizeof(*w->l->ltq));
+    w->ltq_limit = w->l->ltq + g->ltqsize;
+    w->head = w->tail = w->l->ltq;
+    
+    cilk_fiber_pool_init(&w->l->fiber_pool,
+                         &g->fiber_pool,
+                         g->stack_size,
+                         g->fiber_pool_size,
+                         0,   // alloc_max is 0.  We don't allocate from the heap directly without checking the parent pool.
+                         0);
+#if FIBER_DEBUG >= 2
+    fprintf(stderr, "ThreadId=%p: Making w=%d (%p), pool = %p\n",
+            cilkos_get_current_thread_id(),
+            w->self, w, 
+            &w->l->fiber_pool);
+#endif
+    w->l->scheduling_fiber = NULL;
+    w->l->original_pedigree_leaf = NULL;
+    w->l->rand_seed = 0; /* the scheduler will overwrite this field */
+
+    w->l->post_suspend = 0;
+    w->l->suspended_stack = 0;
+    w->l->fiber_to_free = NULL;
+    w->l->pending_exception = NULL;
+
+#if CILK_PROFILE
+    w->l->stats = __cilkrts_malloc(sizeof(statistics));
+    __cilkrts_init_stats(w->l->stats);
+#else
+    w->l->stats = NULL;
+#endif    
+    w->l->steal_failure_count = 0;
+
+    w->l->work_stolen = 0;
+
+    // Initialize record/replay assuming we're doing neither
+    w->l->record_replay_fptr = NULL;
+    w->l->replay_list_root = NULL;
+    w->l->replay_list_entry = NULL;
+    w->l->signal_node = NULL;
+    // Nothing's been stolen yet
+    w->l->worker_magic_1 = WORKER_MAGIC_1;
+
+    /*w->parallelism_disabled = 0;*/
+
+    // Allow stealing all frames. Sets w->saved_protected_tail
+    __cilkrts_restore_stealing(w, w->ltq_limit);
+    
+    __cilkrts_init_worker_sysdep(w);
+
+    reset_THE_exception(w); 
+
+    return w;
+}
+
+void destroy_worker(__cilkrts_worker *w)
+{
+    CILK_ASSERT (NULL == w->l->pending_exception);
+
+    // Deallocate the scheduling fiber
+    if (NULL != w->l->scheduling_fiber)
+    {
+        // The scheduling fiber is the main fiber for system workers and must
+        // be deallocated by the thread that created it.  Thus, we can
+        // deallocate only free workers' (formerly user workers) scheduling
+        // fibers here. 
+        CILK_ASSERT(WORKER_FREE == w->l->type);
+
+#if FIBER_DEBUG >=1
+        fprintf(stderr, "ThreadId=%p, w=%p, %d, deallocating scheduling fiber = %p, \n",
+                cilkos_get_current_thread_id(),
+                w,
+                w->self,
+                w->l->scheduling_fiber);
+#endif
+        int ref_count = cilk_fiber_remove_reference(w->l->scheduling_fiber, NULL);
+        // Scheduling fiber should never have extra references because of exceptions.
+        CILK_ASSERT(0 == ref_count);
+        w->l->scheduling_fiber = NULL;
+    }
+
+#if CILK_PROFILE
+    if (w->l->stats) {
+        __cilkrts_free(w->l->stats);
+    }
+#else
+    CILK_ASSERT(NULL == w->l->stats);
+#endif
+    
+    /* Free any cached fibers. */
+    cilk_fiber_pool_destroy(&w->l->fiber_pool);
+
+    __cilkrts_destroy_worker_sysdep(w);
+
+    if (w->l->signal_node) {
+        CILK_ASSERT(WORKER_SYSTEM == w->l->type);
+        signal_node_destroy(w->l->signal_node);
+    }
+
+    __cilkrts_free(w->l->ltq);
+    __cilkrts_mutex_destroy(0, &w->l->lock);
+    __cilkrts_mutex_destroy(0, &w->l->steal_lock);
+    __cilkrts_frame_malloc_per_worker_cleanup(w);
+
+    __cilkrts_free(w->l);
+
+    // The caller is responsible for freeing the worker memory
+}
+
+/*
+ * Make a worker into a system worker.
+ */
+static void make_worker_system(__cilkrts_worker *w) {
+    CILK_ASSERT(WORKER_FREE == w->l->type);
+    w->l->type = WORKER_SYSTEM;
+    w->l->signal_node = signal_node_create();
+}
+
+void __cilkrts_deinit_internal(global_state_t *g)
+{
+    int i;
+    __cilkrts_worker *w;
+
+    // If there's no global state then we're done
+    if (NULL == g)
+        return;
+
+#ifdef CILK_PROFILE
+    __cilkrts_dump_stats_to_stderr(g);
+#endif
+
+    w = g->workers[0];
+    if (w->l->frame_ff) {
+        __cilkrts_destroy_full_frame(w, w->l->frame_ff);
+        w->l->frame_ff = 0;
+    }
+
+    // Release any resources used for record/replay
+    replay_term(g);
+
+    // Destroy any system dependent global state
+    __cilkrts_destroy_global_sysdep(g);
+
+    for (i = 0; i < g->total_workers; ++i)
+        destroy_worker(g->workers[i]);
+
+    // Free memory for all worker blocks which were allocated contiguously
+    __cilkrts_free(g->workers[0]);
+
+    __cilkrts_free(g->workers);
+
+    cilk_fiber_pool_destroy(&g->fiber_pool);
+    __cilkrts_frame_malloc_global_cleanup(g);
+
+    cilkg_deinit_global_state();
+}
+
+/*
+ * Wake the runtime by notifying the system workers that they can steal.  The
+ * first user worker into the runtime should call this.
+ */
+static void wake_runtime(global_state_t *g)
+{
+    __cilkrts_worker *root;
+    if (g->P > 1) {
+        // Send a message to the root node.  The message will propagate.
+        root = g->workers[0];
+        CILK_ASSERT(root->l->signal_node);
+        signal_node_msg(root->l->signal_node, 1);
+    }
+}
+
+/*
+ * Put the runtime to sleep.  The last user worker out of the runtime should
+ * call this.  Like Dad always said, turn out the lights when nobody's in the
+ * room.
+ */
+static void sleep_runtime(global_state_t *g)
+{
+    __cilkrts_worker *root;
+    if (g->P > 1) {
+        // Send a message to the root node.  The message will propagate.
+        root = g->workers[0];
+        CILK_ASSERT(root->l->signal_node);
+        signal_node_msg(root->l->signal_node, 0);
+    }
+}
+
+/* Called when a user thread joins Cilk.
+   Global lock must be held. */
+void __cilkrts_enter_cilk(global_state_t *g)
+{
+    if (g->Q++ == 0) {
+        // If this is the first user thread to enter Cilk wake
+        // up all the workers.
+        wake_runtime(g);
+    }
+}
+
+/* Called when a user thread leaves Cilk.
+   Global lock must be held. */
+void __cilkrts_leave_cilk(global_state_t *g)
+{
+    if (--g->Q == 0) {
+        // Put the runtime to sleep.
+        sleep_runtime(g);
+    }
+}
+
+/*
+ * worker_runnable
+ *
+ * Return true if the worker should continue to try to steal.  False, otherwise.
+ */
+
+NOINLINE
+static enum schedule_t worker_runnable(__cilkrts_worker *w)
+{
+    global_state_t *g = w->g;
+
+    /* If this worker has something to do, do it.
+       Otherwise the work would be lost. */
+    if (w->l->next_frame_ff)
+        return SCHEDULE_RUN;
+
+    // If Cilk has explicitly (by the user) been told to exit (i.e., by
+    // __cilkrts_end_cilk() -> __cilkrts_stop_workers(g)), then return 0.
+    if (g->work_done)
+        return SCHEDULE_EXIT;
+
+    if (0 == w->self) {
+        // This worker is the root node and is the only one that may query the
+        // global state to see if there are still any user workers in Cilk.
+        if (w->l->steal_failure_count > g->max_steal_failures) {
+            if (signal_node_should_wait(w->l->signal_node)) {
+                return SCHEDULE_WAIT;
+            } else {
+                // Reset the steal_failure_count since we have verified that
+                // user workers are still in Cilk.
+                w->l->steal_failure_count = 0;
+            }
+        }
+    } else if (WORKER_SYSTEM == w->l->type &&
+               signal_node_should_wait(w->l->signal_node)) {
+        // This worker has been notified by its parent that it should stop
+        // trying to steal.
+        return SCHEDULE_WAIT;
+    }
+
+    return SCHEDULE_RUN;
+}
+
+
+
+// Initialize the worker structs, but don't start the workers themselves.
+static void init_workers(global_state_t *g)
+{
+    int total_workers = g->total_workers;
+    int i;
+    struct CILK_ALIGNAS(256) buffered_worker {
+        __cilkrts_worker w;
+        char buf[64];
+    } *workers_memory;
+
+    /* not needed if only one worker */
+    cilk_fiber_pool_init(&g->fiber_pool,
+                         NULL,
+                         g->stack_size,
+                         g->global_fiber_pool_size,           // buffer_size
+                         g->max_stacks,                       // maximum # to allocate
+                         1);
+
+    cilk_fiber_pool_set_fiber_limit(&g->fiber_pool,
+                                    (g->max_stacks ? g->max_stacks : INT_MAX));
+
+    g->workers = (__cilkrts_worker **)
+        __cilkrts_malloc(total_workers * sizeof(*g->workers));
+
+    // Allocate 1 block of memory for workers to make life easier for tools
+    // like Inspector which run multithreaded and need to know the memory
+    // range for all the workers that will be accessed in a user's program
+    workers_memory = (struct buffered_worker*)
+        __cilkrts_malloc(sizeof(*workers_memory) * total_workers);    
+    
+    // Notify any tools that care (Cilkscreen and Inspector) that they should
+    // ignore memory allocated for the workers
+    __cilkrts_cilkscreen_ignore_block(&workers_memory[0],
+                                      &workers_memory[total_workers]);
+
+    // Initialize worker structs, including unused worker slots.
+    for (i = 0; i < total_workers; ++i) {
+        g->workers[i] = make_worker(g, i, &workers_memory[i].w);
+    }
+
+    // Set the workers in the first P - 1 slots to be system workers.
+    // Remaining worker structs already have type == 0.
+    for (i = 0; i < g->system_workers; ++i) {
+        make_worker_system(g->workers[i]);
+    }
+}
+
+void __cilkrts_init_internal(int start)
+{
+    global_state_t *g = NULL;
+
+    if (cilkg_is_published()) {
+        g = cilkg_init_global_state();
+    }
+    else {
+
+        // We think the state has not been published yet.
+        // Grab the lock and try to initialize/publish.
+        global_os_mutex_lock();
+
+        if (cilkg_is_published()) {
+            // Some other thread must have snuck in and published.
+            g = cilkg_init_global_state();
+        }
+        else {
+            // Initialize and retrieve global state
+            g = cilkg_init_global_state();
+
+            // Set the scheduler pointer
+            g->scheduler = worker_scheduler_function;
+
+            // If we're running under a sequential P-Tool (Cilkscreen or
+            // Cilkview) then there's only one worker and we need to tell
+            // the tool about the extent of the stack
+            if (g->under_ptool)
+                __cilkrts_establish_c_stack();     
+            init_workers(g);
+
+            // Initialize per-work record/replay logging
+            replay_init_workers(g);
+
+            // Initialize any system dependent global state
+            __cilkrts_init_global_sysdep(g);
+
+
+            cilkg_publish_global_state(g);
+        }
+
+        global_os_mutex_unlock();
+    }
+
+    CILK_ASSERT(g);
+
+    if (start && !g->workers_running)
+    {
+        // Acquire the global OS mutex while we're starting the workers
+        global_os_mutex_lock();
+        if (!g->workers_running)
+            // Start P - 1 system workers since P includes the first user
+            // worker.
+            __cilkrts_start_workers(g, g->P - 1);
+        global_os_mutex_unlock();
+    }
+}
+
+
+/************************************************************************
+  Methods for reducer protocol.
+
+  Reductions occur in two places:
+    A. A full frame "ff" is returning from a spawn with a stolen parent.
+    B. A full frame "ff" is stalling at a sync.
+
+  To support parallel reductions, reduction functions need to be
+  executed while control is on a user stack, before jumping into the
+  runtime.  These reductions can not occur while holding a worker or
+  frame lock.
+
+  Before a worker w executes a reduction in either Case A or B, w's
+  deque is empty.
+
+  Since parallel reductions push work onto the deque, we must do extra
+  work to set up runtime data structures properly before reductions
+  begin to allow stealing.  ( Normally, when we have only serial
+  reductions, once a worker w starts a reduction, its deque remains
+  empty until w either steals another frame or resumes a suspended
+  frame.  Thus, we don't care about the state of the deque, since w
+  will reset its deque when setting up execution of a frame. )
+
+  To allow for parallel reductions, we coerce the runtime data
+  structures so that, from their perspective, it looks as though we
+  have spliced in an "execute_reductions()" function.  Consider the
+  two cases for reductions:
+
+    Case A: Return from a spawn with a stolen parent.
+      Consider a spawned function g is returning on a worker w.
+      Assume:
+          -   g was spawned from a parent function f.  
+          -   ff is the full frame for g's spawn helper
+          -   sf be the __cilkrts_stack_frame for g's spawn helper.
+
+      We are conceptually splicing "execute_reductions()" so that it
+      occurs immediately before the spawn helper of g returns to f.
+
+      We do so by creating two different world views --- one for the
+      runtime data structures, and one for the actual control flow.
+
+        - Before reductions begin, the runtime data structures should
+          look as though the spawn helper of g is calling
+          "execute_reductions()", in terms of both the user stack and
+          worker deque.  More precisely, w should satisfy the
+          following properties:
+
+              (a) w has ff as its full frame,
+              (b) w has sf as its __cilkrts_stack_frame, and
+              (c) w has an empty deque. 
+
+          If the runtime satisfies these properties, then if w
+          encounters a spawn in a parallel reduction, it can push onto
+          a valid deque.  Also, when a steal from w occurs, it will
+          build the correct tree of full frames when w is stolen from.
+
+        - In actual control flow, however, once the
+          "execute_reductions()" function returns, it is actually
+          returning to runtime code instead of g's spawn helper. 
+
+          At the point a worker w began executing reductions, the
+          control flow / compiled code had already finished g's spawn
+          helper, and w was about to enter the runtime.  With parallel
+          reductions, some worker v (which might be different from w)
+          is the one returning to the runtime.
+
+
+      The reduction logic consists of 4 steps:
+
+       A1. Restore runtime data structures to make it look as though
+           the spawn helper of g() is still the currently executing
+           frame for w.
+
+       A2. Execute reductions on the user stack.  Reductions also
+           includes the logic for exceptions and stacks.  Note that
+           reductions start on w, but may finish on a different
+           worker if there is parallelism in the reduce.
+
+       A3. Splice out ff from the tree of full frames.
+
+       A4. Jump into the runtime/scheduling stack and execute
+           "do_return_from_spawn".  This method
+
+           (a) Frees the user stack we were just on if it is no longer needed.
+           (b) Decrement the join counter on ff->parent, and tries to do a
+               provably good steal.
+           (c) Clean up the full frame ff. 
+
+
+   Case B: Stalling at a sync.
+
+     Consider a function g(), with full frame ff and
+     __cilkrts_stack_frame sf.  Suppose g() stalls at a sync, and we
+     are executing reductions.
+
+     Conceptually, we are splicing in an "execute_reductions()"
+     function into g() as the last action that g() takes immediately
+     before it executes the cilk_sync.
+
+     The reduction logic for this case is similar to Case A.
+
+       B1. Restore the runtime data structures. 
+
+           The main difference from Case A is that ff/sf is still a
+           frame that needs to be executed later (since it is stalling
+           at a cilk_sync).  Thus, we also need to save the current
+           stack information into "ff" so that we can correctly resume
+           execution of "ff" after the sync.
+
+       B2. Execute reductions on the user stack.
+
+       B3. No frame to splice out of the tree.
+
+       B4. Jump into the runtime/scheduling stack and execute "do_sync".
+           This method:
+           (a) Frees the user stack we were just on if it is no longer needed.
+           (b) Tries to execute a provably good steal.
+
+  Finally, for the reducer protocol, we consider two reduction paths,
+  namely a "fast" and "slow" path.  On a fast path, only trivial
+  merges of reducer maps happen (i.e., one or both of the maps are
+  NULL).  Otherwise, on the slow path, a reduction actually needs to
+  happen.
+
+*****************************************************************/
+
+/**
+ * @brief Locations to store the result of a reduction.
+ *
+ * Struct storing pointers to the fields in our "left" sibling that we
+ * should update when splicing out a full frame or stalling at a sync.
+ */
+typedef struct {
+    /** A pointer to the location of our left reducer map. */
+    struct cilkred_map **map_ptr;
+
+    /** A pointer to the location of our left exception. */
+    struct pending_exception_info **exception_ptr;
+} splice_left_ptrs;
+
+/**
+ * For a full frame returning from a spawn, calculate the pointers to
+ * the maps and exceptions to my left.
+ *
+ * @param w   The currently executing worker.
+ * @param ff  Full frame that is dying
+ * @return    Pointers to our "left" for reducers and exceptions.
+ */
+static inline
+splice_left_ptrs compute_left_ptrs_for_spawn_return(__cilkrts_worker *w,
+                                                    full_frame *ff)
+{
+    // ASSERT: we hold the lock on ff->parent
+
+    splice_left_ptrs left_ptrs;
+    if (ff->left_sibling) {
+        left_ptrs.map_ptr = &ff->left_sibling->right_reducer_map;
+        left_ptrs.exception_ptr = &ff->left_sibling->right_pending_exception;
+    }
+    else {
+        full_frame *parent_ff = ff->parent;
+        left_ptrs.map_ptr = &parent_ff->children_reducer_map;
+        left_ptrs.exception_ptr = &parent_ff->child_pending_exception;
+    }
+    return left_ptrs;
+}
+
+/**
+ * For a full frame at a sync, calculate the pointers to the maps and
+ * exceptions to my left.
+ *
+ * @param w   The currently executing worker.
+ * @param ff  Full frame that is stalling at a sync.
+ * @return    Pointers to our "left" for reducers and exceptions.
+ */
+static inline
+splice_left_ptrs compute_left_ptrs_for_sync(__cilkrts_worker *w,
+                                            full_frame *ff)
+{
+    // ASSERT: we hold the lock on ff
+    splice_left_ptrs left_ptrs;
+
+    // Figure out which map to the left we should merge into.
+    if (ff->rightmost_child) {
+        CILK_ASSERT(ff->rightmost_child->parent == ff);
+        left_ptrs.map_ptr = &(ff->rightmost_child->right_reducer_map);
+        left_ptrs.exception_ptr = &(ff->rightmost_child->right_pending_exception);
+    }
+    else {
+        // We have no children.  Then, we should be the last
+        // worker at the sync... "left" is our child map.
+        left_ptrs.map_ptr = &(ff->children_reducer_map);
+        left_ptrs.exception_ptr = &(ff->child_pending_exception);
+    }
+    return left_ptrs;
+}
+
+/**
+ * After we have completed all reductions on a spawn return, call this
+ * method to finish up before jumping into the runtime.
+ *
+ *   1. Perform the "reduction" on stacks, i.e., execute the left
+ *      holder logic to pass the leftmost stack up.
+ *
+ *      w->l->fiber_to_free holds any stack that needs to be freed
+ *      when control switches into the runtime fiber.
+ * 
+ *   2. Unlink and remove child_ff from the tree of full frames.
+ *
+ * @param   w          The currently executing worker.
+ * @param   parent_ff  The parent of child_ff.
+ * @param   child_ff   The full frame returning from a spawn.
+ */
+static inline
+void finish_spawn_return_on_user_stack(__cilkrts_worker *w,
+                                       full_frame *parent_ff,
+                                       full_frame *child_ff)
+{
+    CILK_ASSERT(w->l->fiber_to_free == NULL);
+
+    // Execute left-holder logic for stacks.
+    if (child_ff->left_sibling || parent_ff->fiber_child) {
+        // Case where we are not the leftmost stack.
+        CILK_ASSERT(parent_ff->fiber_child != child_ff->fiber_self);
+
+        // Remember any fiber we need to free in the worker.
+        // After we jump into the runtime, we will actually do the
+        // free.
+        w->l->fiber_to_free = child_ff->fiber_self;
+    }
+    else {
+        // We are leftmost, pass stack/fiber up to parent.
+        // Thus, no stack/fiber to free.
+        parent_ff->fiber_child = child_ff->fiber_self;
+        w->l->fiber_to_free = NULL;
+    }
+
+    child_ff->fiber_self = NULL;
+
+    unlink_child(parent_ff, child_ff);
+}
+
+
+/**
+ * Executes any fast reductions necessary to splice ff out of the tree
+ * of full frames.
+ *
+ * This "fast" path performs only trivial merges of reducer maps,
+ * i.e,. when one of them is NULL.
+ * (See slow_path_reductions_for_spawn_return() for slow path.)
+ *
+ * Returns: 1 if we finished all reductions.
+ * Returns: 0 if there are still reductions to execute, and
+ *            we should execute the slow path.
+ *
+ * This method assumes w holds the frame lock on parent_ff.
+ * After this method completes:
+ *    1. We have spliced ff out of the tree of full frames.
+ *    2. The reducer maps of child_ff have been deposited
+ *       "left" according to the reducer protocol.
+ *    3. w->l->stack_to_free stores the stack
+ *       that needs to be freed once we jump into the runtime.
+ *
+ * We have not, however, decremented the join counter on ff->parent.
+ * This prevents any other workers from resuming execution of the parent.
+ *
+ * @param   w    The currently executing worker.
+ * @param   ff   The full frame returning from a spawn.
+ * @return  NULL if we finished all reductions.
+ * @return  The address where the left map is stored (which should be passed to 
+ *          slow_path_reductions_for_spawn_return()) if there are
+ *          still reductions to execute. 
+ */
+struct cilkred_map**
+fast_path_reductions_for_spawn_return(__cilkrts_worker *w,
+                                      full_frame *ff)
+{
+    // ASSERT: we hold ff->parent->lock.
+    splice_left_ptrs left_ptrs;
+
+    CILK_ASSERT(NULL == w->l->pending_exception);
+
+    // Figure out the pointers to the left where I want
+    // to put reducers and exceptions.
+    left_ptrs = compute_left_ptrs_for_spawn_return(w, ff);
+    
+    // Go ahead and merge exceptions while holding the lock.
+    splice_exceptions_for_spawn(w, ff, left_ptrs.exception_ptr);
+
+    // Now check if we have any reductions to perform.
+    //
+    // Consider all the cases of left, middle and right maps.
+    //  0. (-, -, -)  :  finish and return 1
+    //  1. (L, -, -)  :  finish and return 1
+    //  2. (-, M, -)  :  slide over to left, finish, and return 1.
+    //  3. (L, M, -)  :  return 0
+    //  4. (-, -, R)  :  slide over to left, finish, and return 1.
+    //  5. (L, -, R)  :  return 0
+    //  6. (-, M, R)  :  return 0
+    //  7. (L, M, R)  :  return 0
+    //
+    // In terms of code:
+    //  L == *left_ptrs.map_ptr
+    //  M == w->reducer_map
+    //  R == f->right_reducer_map.
+    //
+    // The goal of the code below is to execute the fast path with
+    // as few branches and writes as possible.
+    
+    int case_value = (*(left_ptrs.map_ptr) != NULL);
+    case_value += ((w->reducer_map != NULL) << 1);
+    case_value += ((ff->right_reducer_map != NULL) << 2);
+
+    // Fastest path is case_value == 0 or 1.
+    if (case_value >=2) {
+        switch (case_value) {
+        case 2:
+            *(left_ptrs.map_ptr) = w->reducer_map;
+            w->reducer_map = NULL;
+            return NULL;
+            break;
+        case 4:
+            *(left_ptrs.map_ptr) = ff->right_reducer_map;
+            ff->right_reducer_map = NULL;
+            return NULL;
+        default:
+            // If we have to execute the slow path, then
+            // return the pointer to the place to deposit the left
+            // map.
+            return left_ptrs.map_ptr;
+        }
+    }
+
+    // Do nothing
+    return NULL;
+}
+
+
+/**
+ * Executes any reductions necessary to splice "ff" frame out of
+ * the steal tree.
+ *
+ * This method executes the "slow" path for reductions on a spawn
+ * return, i.e., there are non-NULL maps that need to be merged
+ * together.
+ *
+ * This method should execute only if
+ * fast_path_reductions_for_spawn_return() returns a non-NULL
+ * left_map_ptr.
+ *
+ * Upon entry, left_map_ptr should be the location of the left map
+ * at the start of the reduction, as calculated by
+ * fast_path_reductions_for_spawn_return().
+ *
+ * After this method completes:
+ *    1. We have spliced ff out of the tree of full frames.
+ *    2. The reducer maps of child_ff have been deposited
+ *       "left" according to the reducer protocol.
+ *    3. w->l->stack_to_free stores the stack
+ *       that needs to be freed once we jump into the runtime.
+ * We have not, however, decremented the join counter on ff->parent,
+ * so no one can resume execution of the parent yet.
+ *
+ * WARNING: 
+ *   This method assumes the lock on ff->parent is held upon entry, and
+ *   Upon exit, the worker that returns still holds a lock on ff->parent
+ *   This method can, however, release and reacquire the lock on ff->parent.
+ *
+ * @param w             The currently executing worker.
+ * @param ff            The full frame returning from a spawn.
+ * @param left_map_ptr  Pointer to our initial left map.
+ * @return              The worker that this method returns on. 
+ */ 
+static __cilkrts_worker*
+slow_path_reductions_for_spawn_return(__cilkrts_worker *w,
+                                      full_frame *ff,
+                                      struct cilkred_map **left_map_ptr)
+{
+
+    // CILK_ASSERT: w is holding frame lock on parent_ff.
+#if REDPAR_DEBUG > 0
+    CILK_ASSERT(!ff->rightmost_child);
+    CILK_ASSERT(!ff->is_call_child);
+#endif
+
+    // Loop invariant:
+    // When beginning this loop, we should
+    //   1. Be holding the lock on ff->parent.
+    //   2. left_map_ptr should be the address of the pointer to the left map.
+    //   3. All maps should be slid over left by one, if possible.
+    //   4. All exceptions should be merged so far.
+    while (1) {
+        
+        // Slide middle map left if possible.
+        if (!(*left_map_ptr)) {
+            *left_map_ptr = w->reducer_map;
+            w->reducer_map = NULL;
+        }
+        // Slide right map to middle if possible.
+        if (!w->reducer_map) {
+            w->reducer_map = ff->right_reducer_map;
+            ff->right_reducer_map = NULL;
+        }
+
+        // Since we slid everything left by one,
+        // we are finished if there is no middle map.
+        if (!w->reducer_map) {
+            verify_current_wkr(w);
+            return w;
+        }
+        else {
+            struct cilkred_map* left_map;
+            struct cilkred_map* middle_map;
+            struct cilkred_map* right_map;
+
+            // Take all the maps from their respective locations.
+            // We can't leave them in place and execute a reduction because these fields
+            // might change once we release the lock.
+            left_map = *left_map_ptr;
+            *left_map_ptr = NULL;
+            middle_map = w->reducer_map;
+            w->reducer_map = NULL;
+            right_map = ff->right_reducer_map;
+            ff->right_reducer_map = NULL;
+        
+            // WARNING!!! Lock release here.
+            // We have reductions to execute (and we can't hold locks).
+            __cilkrts_frame_unlock(w, ff->parent);
+
+            // Merge all reducers into the left map.
+            left_map = repeated_merge_reducer_maps(&w,
+                                                   left_map,
+                                                   middle_map);
+            verify_current_wkr(w);
+            left_map = repeated_merge_reducer_maps(&w,
+                                                   left_map,
+                                                   right_map);
+            verify_current_wkr(w);
+            CILK_ASSERT(NULL == w->reducer_map);
+            // Put the final answer back into w->reducer_map.
+            w->reducer_map = left_map;
+            
+            // Save any exceptions generated because of the reduction
+            // process from the returning worker.  These get merged
+            // the next time around the loop.
+            CILK_ASSERT(NULL == ff->pending_exception);
+            ff->pending_exception = w->l->pending_exception;
+            w->l->pending_exception = NULL;
+
+            // Lock ff->parent for the next loop around.
+            __cilkrts_frame_lock(w, ff->parent);
+
+            // Once we have the lock again, recompute who is to our
+            // left.
+            splice_left_ptrs left_ptrs;
+            left_ptrs = compute_left_ptrs_for_spawn_return(w, ff);
+
+            // Update the pointer for the left map.
+            left_map_ptr = left_ptrs.map_ptr;
+            // Splice the exceptions for spawn.
+            splice_exceptions_for_spawn(w, ff, left_ptrs.exception_ptr);
+        }
+    }
+    // We should never break out of this loop.
+    
+    CILK_ASSERT(0);
+    return NULL;
+}
+
+
+
+/**
+ * Execute reductions when returning from a spawn whose parent has
+ * been stolen.
+ *
+ * Execution may start on w, but may finish on a different worker.
+ * This method acquires/releases the lock on ff->parent. 
+ *
+ * @param w            The currently executing worker.
+ * @param ff           The full frame of the spawned function that is returning.
+ * @param returning_sf The __cilkrts_stack_frame for this returning function.
+ * @return             The worker returning from this method. 
+ */ 
+static __cilkrts_worker*
+execute_reductions_for_spawn_return(__cilkrts_worker *w,
+                                    full_frame *ff,
+                                    __cilkrts_stack_frame *returning_sf)
+{ 
+    // Step A1 from reducer protocol described above.
+    //
+    // Coerce the runtime into thinking that 
+    // ff/returning_sf are still on the bottom of
+    // w's deque.
+    restore_frame_for_spawn_return_reduction(w, ff, returning_sf);
+
+    // Step A2 and A3: Execute reductions on user stack.
+    BEGIN_WITH_FRAME_LOCK(w, ff->parent) {
+        struct cilkred_map **left_map_ptr;
+        left_map_ptr = fast_path_reductions_for_spawn_return(w, ff);
+
+        // Pointer will be non-NULL if there are
+        // still reductions to execute.
+        if (left_map_ptr) {
+            // WARNING: This method call may release the lock
+            // on ff->parent and re-acquire it (possibly on a
+            // different worker).
+            // We can't hold locks while actually executing
+            // reduce functions.
+            w = slow_path_reductions_for_spawn_return(w,
+                                                      ff,
+                                                      left_map_ptr);
+            verify_current_wkr(w);
+        }
+
+        finish_spawn_return_on_user_stack(w, ff->parent, ff);      
+        // WARNING: the use of this lock macro is deceptive.
+        // The worker may have changed here.
+    } END_WITH_FRAME_LOCK(w, ff->parent);
+    return w;
+}
+
+
+
+/**
+ * Execute fast "reductions" when ff stalls at a sync.
+ *
+ * @param   w  The currently executing worker.
+ * @param   ff The full frame stalling at a sync.
+ * @return  1 if we are finished with all reductions after calling this method.
+ * @return  0 if we still need to execute the slow path reductions.
+ */ 
+static inline
+int fast_path_reductions_for_sync(__cilkrts_worker *w,
+                                  full_frame *ff) {
+    // Return 0 if there is some reduction that needs to happen.
+    return !(w->reducer_map  || ff->pending_exception);
+}
+
+/**
+ * Executes slow reductions when ff stalls at a sync.
+ * This method should execute only if
+ *   fast_path_reductions_for_sync(w, ff) returned 0.
+ *
+ * After this method completes:
+ *   1. ff's current reducer map has been deposited into
+ *       right_reducer_map of ff's rightmost child, or
+ *       ff->children_reducer_map if ff has no children.
+ *   2. Similarly for ff's current exception.
+ *   3. Nothing to calculate for stacks --- if we are stalling
+ *      we will always free a stack.
+ *
+ * This method may repeatedly acquire/release the lock on ff.
+ *
+ * @param   w  The currently executing worker.
+ * @param   ff The full frame stalling at a sync.
+ * @return  The worker returning from this method.
+ */
+static __cilkrts_worker*
+slow_path_reductions_for_sync(__cilkrts_worker *w,
+                              full_frame *ff)
+{
+    struct cilkred_map *left_map;
+    struct cilkred_map *middle_map;
+    
+#if (REDPAR_DEBUG > 0)
+    CILK_ASSERT(ff);
+    CILK_ASSERT(w->head == w->tail);
+#endif
+
+    middle_map = w->reducer_map;
+    w->reducer_map = NULL;
+
+    // Loop invariant: middle_map should be valid (the current map to reduce). 
+    //                 left_map is junk.
+    //                 w->reducer_map == NULL.
+    while (1) {
+        BEGIN_WITH_FRAME_LOCK(w, ff) {
+            splice_left_ptrs left_ptrs = compute_left_ptrs_for_sync(w, ff);
+            
+            // Grab the "left" map and store pointers to those locations.
+            left_map = *(left_ptrs.map_ptr);
+            *(left_ptrs.map_ptr) = NULL;
+            
+            // Slide the maps in our struct left as far as possible.
+            if (!left_map) {
+                left_map = middle_map;
+                middle_map = NULL;
+            }
+
+            *(left_ptrs.exception_ptr) =
+                __cilkrts_merge_pending_exceptions(w,
+                                                   *left_ptrs.exception_ptr,
+                                                   ff->pending_exception);
+            ff->pending_exception = NULL;
+
+            // If there is no middle map, then we are done.
+            // Deposit left and return.
+            if (!middle_map) {
+                *(left_ptrs).map_ptr = left_map;
+                #if (REDPAR_DEBUG > 0)
+                CILK_ASSERT(NULL == w->reducer_map);
+                #endif
+                // Sanity check upon leaving the loop.
+                verify_current_wkr(w);
+                // Make sure to unlock before we return!
+                __cilkrts_frame_unlock(w, ff);
+                return w;
+            }
+        } END_WITH_FRAME_LOCK(w, ff);
+        
+        // If we get here, we have a nontrivial reduction to execute.
+        middle_map = repeated_merge_reducer_maps(&w,
+                                                 left_map,
+                                                 middle_map);
+        verify_current_wkr(w);
+
+        // Save any exceptions generated because of the reduction
+        // process.  These get merged the next time around the
+        // loop.
+        CILK_ASSERT(NULL == ff->pending_exception);
+        ff->pending_exception = w->l->pending_exception;
+        w->l->pending_exception = NULL;
+    }
+    
+    // We should never break out of the loop above.
+    CILK_ASSERT(0);
+    return NULL;
+}
+
+
+/**
+ * Execute reductions when ff stalls at a sync.
+ *
+ * Execution starts on w, but may finish on a different worker.
+ * This method may acquire/release the lock on ff.
+ *
+ * @param w          The currently executing worker.
+ * @param ff         The full frame of the spawned function at the sync
+ * @param sf_at_sync The __cilkrts_stack_frame stalling at a sync
+ * @return           The worker returning from this method.
+ */ 
+static __cilkrts_worker*
+execute_reductions_for_sync(__cilkrts_worker *w,
+                            full_frame *ff,
+                            __cilkrts_stack_frame *sf_at_sync)
+{
+    int finished_reductions;
+    // Step B1 from reducer protocol above:
+    // Restore runtime invariants.
+    //
+    // The following code for this step is almost equivalent to
+    // the following sequence:
+    //   1. disown(w, ff, sf_at_sync, "sync") (which itself
+    //        calls make_unrunnable(w, ff, sf_at_sync))
+    //   2. make_runnable(w, ff, sf_at_sync).
+    //
+    // The "disown" will mark the frame "sf_at_sync"
+    // as stolen and suspended, and save its place on the stack,
+    // so it can be resumed after the sync. 
+    //
+    // The difference is, that we don't want the disown to 
+    // break the following connections yet, since we are
+    // about to immediately make sf/ff runnable again anyway.
+    //   sf_at_sync->worker == w
+    //   w->l->frame_ff == ff.
+    //
+    // These connections are needed for parallel reductions, since
+    // we will use sf / ff as the stack frame / full frame for
+    // executing any potential reductions.
+    //
+    // TBD: Can we refactor the disown / make_unrunnable code
+    // to avoid the code duplication here?
+
+    ff->call_stack = NULL;
+
+    // Normally, "make_unrunnable" would add CILK_FRAME_STOLEN and
+    // CILK_FRAME_SUSPENDED to sf_at_sync->flags and save the state of
+    // the stack so that a worker can resume the frame in the correct
+    // place.
+    //
+    // But on this path, CILK_FRAME_STOLEN should already be set.
+    // Also, we technically don't want to suspend the frame until
+    // the reduction finishes.
+    // We do, however, need to save the stack before
+    // we start any reductions, since the reductions might push more
+    // data onto the stack.
+    CILK_ASSERT(sf_at_sync->flags | CILK_FRAME_STOLEN);
+
+    __cilkrts_put_stack(ff, sf_at_sync);
+    __cilkrts_make_unrunnable_sysdep(w, ff, sf_at_sync, 1,
+                                     "execute_reductions_for_sync");
+    CILK_ASSERT(w->l->frame_ff == ff);
+
+    // Step B2: Execute reductions on user stack.
+    // Check if we have any "real" reductions to do.
+    finished_reductions = fast_path_reductions_for_sync(w, ff);
+    
+    if (!finished_reductions) {
+        // Still have some real reductions to execute.
+        // Run them here.
+
+        // This method may acquire/release the lock on ff.
+        w = slow_path_reductions_for_sync(w, ff);
+
+        // The previous call may return on a different worker.
+        // than what we started on.
+        verify_current_wkr(w);
+    }
+
+#if REDPAR_DEBUG >= 0
+    CILK_ASSERT(w->l->frame_ff == ff);
+    CILK_ASSERT(ff->call_stack == NULL);
+#endif
+
+    // Now we suspend the frame ff (since we've
+    // finished the reductions).  Roughly, we've split apart the 
+    // "make_unrunnable" call here --- we've already saved the
+    // stack info earlier before the reductions execute.
+    // All that remains is to restore the call stack back into the
+    // full frame, and mark the frame as suspended.
+    ff->call_stack = sf_at_sync;
+    sf_at_sync->flags |= CILK_FRAME_SUSPENDED;
+
+    // At a nontrivial sync, we should always free the current fiber,
+    // because it can not be leftmost.
+    w->l->fiber_to_free = ff->fiber_self;
+    ff->fiber_self = NULL;
+    return w;
+}
+
+
+/*
+  Local Variables: **
+  c-file-style:"bsd" **
+  c-basic-offset:4 **
+  indent-tabs-mode:nil **
+  End: **
+*/
diff --git a/libcilkrts/runtime/scheduler.h b/libcilkrts/runtime/scheduler.h
new file mode 100644 (file)
index 0000000..543adaf
--- /dev/null
@@ -0,0 +1,421 @@
+/* scheduler.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file scheduler.h
+ *
+ * @brief scheduler.h declares routines for the Intel Cilk Plus scheduler,
+ * making it the heart of the Intel Cilk Plus implementation.
+ */
+
+#ifndef INCLUDED_SCHEDULER_DOT_H
+#define INCLUDED_SCHEDULER_DOT_H
+
+#include <cilk/common.h>
+#include <internal/abi.h>
+
+#include "rts-common.h"
+#include "full_frame.h"
+#include "reducer_impl.h"
+#include "global_state.h"
+
+#ifdef CILK_RECORD_REPLAY
+#include "record-replay.h"
+#endif
+
+__CILKRTS_BEGIN_EXTERN_C
+
+
+/**
+ * @brief Flag to disable parallel reductions.
+ *
+ * Set to 0 to allow parallel reductions.
+ */
+#define DISABLE_PARALLEL_REDUCERS 0
+
+/**
+ * @brief Debugging level for parallel reductions.
+ *
+ * Print debugging messages and assertions for parallel reducers. 0 is
+ * no debugging.  A higher value generates more output.
+ */
+#define REDPAR_DEBUG 0
+
+/**
+ * @brief Lock the worker mutex to allow exclusive access to the
+ * values in the @c __cilkrts_worker and local_state structures.
+ *
+ * @pre @c w->l->do_not_steal must not be set.  Essentially this
+ * condition asserts that the worker is not locked recursively.
+ *
+ * @param w The worker to lock.
+ */
+COMMON_PORTABLE
+void __cilkrts_worker_lock(__cilkrts_worker *w);
+
+/**
+ * @brief Unlock the worker mutex.
+ *
+ * @pre @c w->l->do_not_steal must be set.  Essentially this condition
+ * asserts that the worker has been previously locked.
+ *
+ * @param w The worker to unlock.
+ */
+COMMON_PORTABLE
+void __cilkrts_worker_unlock(__cilkrts_worker *w);
+
+/**
+ * @brief Push the next full frame to be made active in this worker
+ * and increment its join counter.
+ *
+ * __cilkrts_push_next_frame and pop_next_frame work on a one-element queue.
+ * This queue is used to communicate across the runtime from the code that
+ * wants to activate a frame to the code that can actually begin execution
+ * on that frame.  They are asymetrical in that push increments the join
+ * counter but pop does not decrement it.  Rather, a single push/pop
+ * combination makes a frame active and increments its join counter once.
+ *
+ * @note A system worker may chose to push work onto a user worker if
+ * the work is the continuation from a sync which only the user worker
+ * may complete.
+ *
+ * @param w The worker which the frame is to be pushed onto.
+ * @param ff The full_frame which is to be continued by the worker.
+ */
+COMMON_PORTABLE
+void __cilkrts_push_next_frame(__cilkrts_worker *w,
+                               full_frame *ff);
+
+/**
+ * @brief Sync on this worker.
+ *
+ * If this worker is the last to reach the sync, execution may resume
+ * on this worker after the sync.
+ *
+ * If this worker is not the last spawned child to reach the sync,
+ * then execution is suspended and the worker will re-enter the
+ * scheduling loop, looking for work it can steal.
+ *
+ * This function will jump into the runtime to switch to the scheduling
+ * stack to implement most of its logic.
+ *
+ * @param w The worker which is executing the sync.
+ * @param sf The __cilkrts_stack_frame containing the sync.
+ */
+COMMON_PORTABLE
+NORETURN __cilkrts_c_sync(__cilkrts_worker *w,
+                          __cilkrts_stack_frame *sf);
+
+/**
+ * @brief Worker @c w completely promotes its own deque, simulating the case
+ * where the whole deque is stolen.
+ *
+ * We use this mechanism to force the allocation of new storage for
+ * reducers for race-detection purposes.
+ *
+ * This method is called from the reducer lookup logic when
+ * @c g->force_reduce is set.
+ *
+ * @warning Use of "force_reduce" is known to have bugs when run with
+ * more than 1 worker.
+ *
+ * @param w The worker which is to have all entries in its deque
+ * promoted to full frames.
+ */
+COMMON_PORTABLE
+void __cilkrts_promote_own_deque(__cilkrts_worker *w);
+
+/**
+ * Called when a spawned function attempts to return and
+ * __cilkrts_undo_detach() fails. This can happen for two reasons:
+ *
+ * @li If another worker is considering stealing our parent, it bumps the
+ * exception pointer while it did so, which will cause __cilkrts_undo_detach()
+ * to fail. If the other worker didn't complete the steal of our parent, we
+ * still may be able to return to it, either because the steal attempt failed,
+ * or we won the race for the tail pointer.
+ *
+ * @li If the function's parent has been stolen then we cannot return. Instead
+ * we'll longjmp into the runtime to switch onto the scheduling stack to
+ * execute do_return_from_spawn() and determine what to do.  Either this
+ * worker is the last one to the sync, in which case we need to jump to the
+ * sync, or this worker is not the last one to the sync, in which case we'll
+ * abandon this work and jump to the scheduling loop to search for more work
+ * we can steal.
+ *
+ * @param w The worker which attempting to return from a spawn to
+ * a stolen parent.
+ * @param returning_sf The stack frame which is returning. 
+ */
+COMMON_PORTABLE
+void __cilkrts_c_THE_exception_check(__cilkrts_worker *w,
+                                    __cilkrts_stack_frame *returning_sf);
+
+/**
+ * @brief Return an exception to an stolen parent.
+ *
+ * Used by the gcc implementation of exceptions to return an exception
+ * to a stolen parent
+ *
+ * @param w The worker which attempting to return from a spawn with an
+ * exception to a stolen parent.
+ * @param returning_sf The stack frame which is returning.
+ */
+COMMON_PORTABLE
+NORETURN __cilkrts_exception_from_spawn(__cilkrts_worker *w,
+                                       __cilkrts_stack_frame *returning_sf);
+
+/**
+ * @brief Used by the Windows implementations of exceptions to migrate an exception
+ * across fibers.
+ *
+ * Call this function when an exception has been thrown and has to
+ * traverse across a steal.  The exception has already been wrapped
+ * up, so all that remains is to longjmp() into the continuation,
+ * sync, and re-raise it.
+ *
+ * @param sf The __cilkrts_stack_frame for the frame that is attempting to
+ * return an exception to a stolen parent.
+ */
+void __cilkrts_migrate_exception (__cilkrts_stack_frame *sf);
+
+/**
+ * @brief Return from a call, not a spawn, where this frame has ever
+ * been stolen.
+ *
+ * @param w The worker that is returning from a frame which was ever stolen.
+ */
+COMMON_PORTABLE
+void __cilkrts_return(__cilkrts_worker *w);
+
+/**
+ * @brief Special return from the initial frame.
+ *
+ * This method will be called from @c __cilkrts_leave_frame if
+ * @c CILK_FRAME_LAST is set.
+ *
+ * This function will do the things necessary to cleanup, and unbind the
+ * thread from the Intel Cilk Plus runtime.  If this is the last user
+ * worker unbinding from the runtime, all system worker threads will be
+ * suspended.
+ *
+ * @pre @c w must be the currently executing worker, and must be a user
+ * worker.
+ *
+ * @param w The worker that's returning from the initial frame.
+ */
+COMMON_PORTABLE
+void __cilkrts_c_return_from_initial(__cilkrts_worker *w);
+
+/**
+ * @brief Used by exception handling code to pop an entry from the
+ * worker's deque.
+ *
+ * @param w Worker to pop the entry from
+ *
+ * @return __cilkrts_stack_frame of parent call
+ * @return NULL if the deque is empty
+ */
+COMMON_PORTABLE
+__cilkrts_stack_frame *__cilkrts_pop_tail(__cilkrts_worker *w);
+
+/**
+ * @brief Modifies the worker's protected_tail to prevent frames from
+ * being stolen.
+ *
+ * The Dekker protocol has been extended to only steal if head+1 is also
+ * less than protected_tail.
+ *
+ * @param w The worker to be modified.
+ * @param new_protected_tail The new setting for protected_tail, or NULL if the
+ * entire deque is to be protected
+ *
+ * @return Previous value of protected tail.
+ */
+COMMON_PORTABLE
+__cilkrts_stack_frame *volatile *__cilkrts_disallow_stealing(
+    __cilkrts_worker *w,
+    __cilkrts_stack_frame *volatile *new_protected_tail);
+
+/**
+ * @brief Restores the protected tail to a previous state, possibly
+ * allowing frames to be stolen.
+ *
+ * @param w The worker to be modified.
+ * @param saved_protected_tail A previous setting for protected_tail that is
+ * to be restored
+ */
+COMMON_PORTABLE
+void __cilkrts_restore_stealing(
+    __cilkrts_worker *w,
+    __cilkrts_stack_frame *volatile *saved_protected_tail);
+
+/**
+ * @brief Initialize a @c __cilkrts_worker.
+ *
+ * @note The memory for the worker must have been allocated outside
+ * this call.
+ *
+ * @param g The global_state_t.
+ * @param self The index into the global_state's array of workers for this
+ * worker, or -1 if this worker was allocated from the heap and cannot be
+ * stolen from.
+ * @param w The worker to be initialized.
+ *
+ * @return The initialized __cilkrts_worker.
+ */
+COMMON_PORTABLE
+__cilkrts_worker *make_worker(global_state_t *g,
+                              int self,
+                              __cilkrts_worker *w);
+
+/**
+ * @brief Free up any resources allocated for a worker.
+ *
+ * @note The memory for the @c __cilkrts_worker itself must be
+ * deallocated outside this call.
+ *
+ * @param w The worker to be destroyed.
+ */
+COMMON_PORTABLE
+void destroy_worker (__cilkrts_worker *w);
+
+/**
+ * @brief Initialize the runtime.
+ * 
+ * If necessary, allocates and initializes the global state.  If
+ * necessary, unsuspends the system workers.
+ *
+ * @param start Specifies whether the workers are to be unsuspended if
+ * they are suspended.  Allows __cilkrts_init() to start up the runtime without
+ * releasing the system threads.
+ */
+COMMON_PORTABLE
+void __cilkrts_init_internal(int start);
+
+/**
+ * @brief Part of the sequence to shutdown the runtime.
+ *
+ * Specifically, this call frees the @c global_state_t for the runtime.
+ *
+ * @param g The global_state_t.
+ */
+COMMON_PORTABLE
+void __cilkrts_deinit_internal(global_state_t *g);
+
+/**
+ * Obsolete.  We no longer need to import or export reducer maps.
+ */
+COMMON_PORTABLE
+cilkred_map *__cilkrts_xchg_reducer(
+    __cilkrts_worker *w, cilkred_map *newmap) cilk_nothrow;
+
+/**
+ * @brief Called when a user thread is bound to the runtime.
+ *
+ * If this action increments the count of bound user threads from 0 to
+ * 1, the system worker threads are unsuspended.
+ *
+ * If this action increments the count of bound user threads from 0 to
+ * 1, the system worker threads are unsuspended.
+ *
+ * @pre Global lock must be held.
+ * @param g The runtime global state.
+ */
+COMMON_PORTABLE
+void __cilkrts_enter_cilk(global_state_t *g);
+
+/**
+ * @brief Called when a user thread is unbound from the runtime.
+ *
+ * If this action decrements the count of bound user threads to 0, the
+ * system worker threads are suspended.
+ *
+ *
+ * @pre  Global lock must be held.
+ *
+ * @param g The runtime global state.
+ */
+COMMON_PORTABLE
+void __cilkrts_leave_cilk(global_state_t *g);
+
+
+/**
+ * @brief cilk_fiber_proc that runs the main scheduler loop on a
+ * user worker.
+ *
+ * @pre  fiber's owner field should be set to the correct __cilkrts_worker
+ * @pre  fiber must be a user worker.
+ *
+ * @param fiber    The scheduling fiber object.
+ */
+void scheduler_fiber_proc_for_user_worker(cilk_fiber *fiber);
+
+
+/**
+ * @brief Prints out Cilk runtime statistics.
+ *
+ * @param g The runtime global state.
+ *
+ * This method is useful only for debugging purposes.  No guarantees
+ * are made as to the validity of this data. :)
+ */
+COMMON_PORTABLE
+void __cilkrts_dump_stats_to_stderr(global_state_t *g);
+
+#ifdef CILK_RECORD_REPLAY
+COMMON_PORTABLE
+char * walk_pedigree_nodes(char *p, const __cilkrts_pedigree *pnode);
+
+/**
+ * @brief Used by exception handling code to simulate the popping of
+ * an entry from the worker's deque.
+ *
+ * @param w Worker whose deque we want to check
+ *
+ * @return @c __cilkrts_stack_frame of parent call
+ * @return NULL if the deque is empty
+ */
+COMMON_PORTABLE
+__cilkrts_stack_frame *simulate_pop_tail(__cilkrts_worker *w);
+
+#endif
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_SCHEDULER_DOT_H)
diff --git a/libcilkrts/runtime/signal_node.c b/libcilkrts/runtime/signal_node.c
new file mode 100644 (file)
index 0000000..92c404b
--- /dev/null
@@ -0,0 +1,241 @@
+/* signal_node.c               -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2011-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+#include "signal_node.h"
+#include <stdlib.h>
+
+/* Define cilk_semaphore_t for all of the respective systems. */
+#if defined __APPLE__
+#   include <mach/mach_init.h>
+#   include <mach/semaphore.h>
+#   include <mach/task.h>
+    typedef semaphore_t cilk_semaphore_t;
+#elif defined _WIN32
+#   include "windows-clean.h"
+    typedef HANDLE cilk_semaphore_t;
+#else // Linux/MIC
+#   include <errno.h>
+#   include <semaphore.h>
+#   include <stdio.h>
+    typedef sem_t cilk_semaphore_t;
+#endif // Linux/MIC
+
+#include "bug.h"
+#include "cilk_malloc.h"
+#include "signal_node.h"
+
+/**
+ * Interface within the tree to notify workers to wait without consuming cycles
+ * to expend cycles trying to steal.
+ *
+ * cilk_semaphore_t is implemented as an auto-reset event on Windows, and
+ * as a semaphore_t on Linux and MacOS.
+ */
+struct signal_node_t
+{
+    /** 0 if the worker should wait, 1 if it should be running. */
+    volatile unsigned int run;
+
+    /** OS-specific semaphore on which the worker can wait. */
+    cilk_semaphore_t sem;
+};
+
+/******************************************************************************/
+/* Semaphore-abstraction functions                                            */
+/******************************************************************************/
+
+/*
+ * All of these functions are simple wrappers for the system-specific semaphore
+ * functions.  This keeps the rest of the code reasonably clean and readable.
+ */
+
+#if defined __APPLE__
+static void initialize_cilk_semaphore (cilk_semaphore_t *sem)
+{
+    kern_return_t kstatus
+        = semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, 0);
+    assert(kstatus == KERN_SUCCESS);
+}
+static void deinitialize_cilk_semaphore (cilk_semaphore_t *sem)
+{
+    kern_return_t kstatus = semaphore_destroy(mach_task_self(), *sem);
+    assert(kstatus == KERN_SUCCESS);
+}
+static void wait_on_cilk_semaphore (cilk_semaphore_t *sem)
+{
+    kern_return_t kstatus = semaphore_wait(*sem);
+    assert(kstatus == KERN_SUCCESS);
+}
+static void signal_cilk_semaphore (cilk_semaphore_t *sem)
+{
+    kern_return_t kstatus = semaphore_signal(*sem);
+    assert(kstatus == KERN_SUCCESS);
+}
+#elif defined _WIN32
+// Note: Windows only provides counting semaphores, and we don't really
+// care about the count. So this is implemented using an auto-reset
+// event which will automatically reset after the WaitForSingleObject
+// call
+static void initialize_cilk_semaphore (cilk_semaphore_t *sem)
+{
+    // Create an auto-reset event
+    *sem = CreateEvent(NULL,    // Security attributes
+                       FALSE,   // Manual reset
+                       FALSE,   // Initial state (initially reset)
+                       NULL);   // Name (anonymous)
+    CILK_ASSERT (NULL != *sem);
+}
+
+static void deinitialize_cilk_semaphore (cilk_semaphore_t *sem)
+{
+    BOOL result = CloseHandle(*sem);
+    CILK_ASSERT (0 != result);
+}
+
+static void wait_on_cilk_semaphore (cilk_semaphore_t *sem)
+{
+    // WaitForSingleObject will reset the event
+    DWORD result = WaitForSingleObject (*sem, INFINITE);
+    CILK_ASSERT (WAIT_OBJECT_0 == result);
+}
+static void signal_cilk_semaphore (cilk_semaphore_t *sem)
+{
+    BOOL result = SetEvent (*sem);
+    CILK_ASSERT (0 != result);
+}
+#else // Linux/MIC
+static void initialize_cilk_semaphore (cilk_semaphore_t *sem)
+{
+    int status = sem_init(sem, 0, 0);
+    assert(0 == status);
+}
+static void deinitialize_cilk_semaphore (cilk_semaphore_t *sem)
+{
+    int status = sem_destroy(sem);
+    assert(0 == status);
+}
+static void wait_on_cilk_semaphore (cilk_semaphore_t *sem)
+{
+    int status;
+
+    do {
+        status = sem_wait(sem);
+    } while (status != 0 && errno == EINTR);
+
+    if (status != 0) {
+        perror("sem_wait");
+        abort();
+    }
+}
+static void signal_cilk_semaphore (cilk_semaphore_t *sem)
+{
+    sem_post(sem);
+}
+#endif // Linux/MIC
+
+/******************************************************************************/
+/* Runtime interface functions                                                */
+/******************************************************************************/
+
+/*
+ * Return a newly malloc'd and initialized signal_node_t.
+ */
+COMMON_SYSDEP
+signal_node_t *signal_node_create(void)
+{
+     signal_node_t *node;
+
+    node = ( signal_node_t*)
+        __cilkrts_malloc(sizeof( signal_node_t));
+    node->run = 0;
+    initialize_cilk_semaphore(&node->sem);
+
+    return node;
+}
+
+/*
+ * Clean and free a signal_node_t.
+ */
+void signal_node_destroy(signal_node_t *node)
+{
+    CILK_ASSERT(node);
+    deinitialize_cilk_semaphore(&node->sem);
+    __cilkrts_free(node);
+}
+
+/*
+ * Return 1 if the node thinks the worker should go to sleep, 0 otherwise.
+ */
+unsigned int signal_node_should_wait(signal_node_t *node)
+{
+    CILK_ASSERT(node);
+    return !node->run;
+}
+
+/*
+ * Send a message to the node that the worker will eventually read.
+ */
+void signal_node_msg(signal_node_t *node, unsigned int msg)
+{
+    CILK_ASSERT(node);
+    switch (msg) {
+    case 0:                    // worker should go to sleep.
+        node->run = msg;
+        break;
+    case 1:                    // worker should be awake.
+        node->run = msg;
+        signal_cilk_semaphore(&node->sem);
+        break;
+    default:                   // error.
+        CILK_ASSERT(0 == "Bad signal_node_t message.");
+    }
+}
+
+/*
+ * The current worker will wait on the semaphore.
+ */
+void signal_node_wait(signal_node_t *node)
+{
+    CILK_ASSERT(node);
+    while (signal_node_should_wait(node)) {
+        // The loop is here to consume extra semaphore signals that might have
+        // accumulated.  No point in passing on the accumulation.
+        wait_on_cilk_semaphore(&node->sem);
+    }
+}
diff --git a/libcilkrts/runtime/signal_node.h b/libcilkrts/runtime/signal_node.h
new file mode 100644 (file)
index 0000000..0a1fe20
--- /dev/null
@@ -0,0 +1,109 @@
+/* signal_node.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file signal_node.h
+ *
+ * @brief Signal nodes allow coordinated waking and sleeping of the runtime
+ * without hammering on a single location in memory.
+ *
+ * The workers are logically arranged in a binary tree and propagate messages
+ * leaf-ward.  User workers notify the root about waking and sleeping, so only
+ * that one node need share a cache line with a user worker.
+ */
+
+#ifndef INCLUDED_SIGNAL_NODE_DOT_H
+#define INCLUDED_SIGNAL_NODE_DOT_H
+
+#include "rts-common.h"
+#include <cilk/common.h>
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/** Opaque type. */
+typedef struct signal_node_t signal_node_t;
+
+/**
+ * Allocate and initialize a signal_node_t
+ *
+ * @return The initialized signal_node_t
+ */
+COMMON_SYSDEP
+signal_node_t *signal_node_create(void);
+
+/**
+ * Free any resources and deallocate a signal_node_t
+ *
+ * @param node The node to be deallocated.
+ */
+COMMON_SYSDEP void signal_node_destroy(signal_node_t *node);
+
+/**
+ * Test whether the node thinks the worker should go to sleep
+ *
+ * @param node The node to be tested.
+ *
+ * @return 1 If the worker should go to sleep
+ * @return 0 If the worker should not go to sleep
+ */
+COMMON_SYSDEP
+unsigned int signal_node_should_wait(signal_node_t *node);
+
+/**
+ * Specify whether the worker should go to sleep
+ *
+ * @param node The node to be set.
+ * @param msg The value to be set.  Valid values are:
+ * - 0 - the worker should go to sleep
+ * - 1 - the worker should stay active
+ */
+COMMON_SYSDEP
+void signal_node_msg(signal_node_t *node, unsigned int msg);
+
+
+/**
+ * Wait for the node to be set
+ *
+ * @param node The node to wait on
+ */
+COMMON_SYSDEP
+void signal_node_wait(signal_node_t *node);
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_SIGNAL_NODE_DOT_H)
diff --git a/libcilkrts/runtime/spin_mutex.c b/libcilkrts/runtime/spin_mutex.c
new file mode 100644 (file)
index 0000000..03908f2
--- /dev/null
@@ -0,0 +1,109 @@
+/* spin_mutex.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#include "spin_mutex.h"
+#include "bug.h"
+#include "os.h"
+#include "stats.h"
+
+// TBD (11/30/12): We should be doing a conditional test-xchg instead
+// of an unconditional xchg operation for the spin mutex.
+
+/* m->lock == 1 means that mutex M is locked */
+#define TRY_ACQUIRE(m) (__cilkrts_xchg(&(m)->lock, 1) == 0)
+
+/* ICC 11.1+ understands release semantics and generates an
+   ordinary store with a software memory barrier. */
+#if __ICC >= 1110
+#define RELEASE(m) __sync_lock_release(&(m)->lock)
+#else
+#define RELEASE(m) __cilkrts_xchg(&(m)->lock, 0)
+#endif
+
+
+spin_mutex* spin_mutex_create() 
+{
+    spin_mutex* mutex = (spin_mutex*)__cilkrts_malloc(sizeof(spin_mutex));
+    spin_mutex_init(mutex);
+    return mutex;
+}
+
+void spin_mutex_init(struct spin_mutex *m)
+{
+    // Use a simple assignment so Inspector doesn't bug us about the
+    // interlocked exchange doing a read of an uninitialized variable.
+    // By definition there can't be a race when we're initializing the
+    // lock...
+    m->lock = 0;
+}
+
+void spin_mutex_lock(struct spin_mutex *m)
+{
+    int count;
+    const int maxspin = 1000; /* SWAG */
+    if (!TRY_ACQUIRE(m)) {
+        count = 0;
+        do {
+            do {
+                __cilkrts_short_pause();
+                if (++count >= maxspin) {
+                    /* let the OS reschedule every once in a while */
+                    __cilkrts_yield();
+                    count = 0;
+                }
+            } while (m->lock != 0);
+        } while (!TRY_ACQUIRE(m));
+    }
+}
+
+int spin_mutex_trylock(struct spin_mutex *m)
+{
+    return TRY_ACQUIRE(m);
+}
+
+void spin_mutex_unlock(struct spin_mutex *m)
+{
+    RELEASE(m);
+}
+
+void spin_mutex_destroy(struct spin_mutex *m)
+{
+    __cilkrts_free(m);
+}
+
+/* End spin_mutex.c */
diff --git a/libcilkrts/runtime/spin_mutex.h b/libcilkrts/runtime/spin_mutex.h
new file mode 100644 (file)
index 0000000..b0045ab
--- /dev/null
@@ -0,0 +1,129 @@
+/* spin_mutex.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file spin_mutex.h
+ *
+ * @brief Support for Cilk runtime mutexes.
+ *
+ * Cilk runtime mutexes are implemented as simple spin loops.
+ *
+ * This file is similar to a worker_mutex, except it does not have an
+ * owner field.
+ *
+ * TBD: This class, worker_mutex, and os_mutex overlap quite a bit in
+ * functionality.  Can we unify these mutexes somehow?
+ */
+#ifndef INCLUDED_SPIN_MUTEX_DOT_H
+#define INCLUDED_SPIN_MUTEX_DOT_H
+
+#include <cilk/common.h>
+#include "rts-common.h"
+#include "cilk_malloc.h"
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * Mutexes are treated as an abstract data type within the Cilk
+ * runtime system.  They are implemented as simple spin loops.
+ */
+typedef struct spin_mutex {
+    /** Mutex spin loop variable. 0 if unowned, 1 if owned. */
+    volatile int lock;
+
+    /** Padding so the mutex takes up a cache line. */
+    char pad[64/sizeof(int) - 1];
+} spin_mutex;
+
+
+/**
+ * @brief Create a new Cilk spin_mutex.
+ *
+ * @return Returns an initialized spin mutex.  
+ */
+COMMON_PORTABLE
+spin_mutex* spin_mutex_create();
+
+/**
+ * @brief Initialize a Cilk spin_mutex.
+ *
+ * @param m Spin_Mutex to be initialized.
+ */
+COMMON_PORTABLE
+void spin_mutex_init(spin_mutex *m);
+
+/**
+ * @brief Acquire a Cilk spin_mutex.
+ *
+ * If statistics are being gathered, the time spent
+ * acquiring the spin_mutex will be attributed to the specified worker.
+ *
+ * @param m Spin_Mutex to be initialized.
+ */
+COMMON_PORTABLE
+void spin_mutex_lock(struct spin_mutex *m);
+/**
+ * @brief Attempt to lock a Cilk spin_mutex and fail if it isn't available.
+ *
+ * @param m Spin_Mutex to be acquired.
+ *
+ * @return 1 if the spin_mutex was acquired.
+ * @return 0 if the spin_mutex was not acquired.
+ */
+COMMON_PORTABLE
+int spin_mutex_trylock(struct spin_mutex *m);
+
+/**
+ * @brief Release a Cilk spin_mutex.
+ *
+ * @param m Spin_Mutex to be released.
+ */
+COMMON_PORTABLE
+void spin_mutex_unlock(struct spin_mutex *m);
+
+/**
+ * @brief Deallocate a Cilk spin_mutex.  Currently does nothing.
+ *
+ * @param m Spin_Mutex to be deallocated.
+ */
+COMMON_PORTABLE
+void spin_mutex_destroy(struct spin_mutex *m);
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_SPIN_MUTEX_DOT_H)
diff --git a/libcilkrts/runtime/stats.c b/libcilkrts/runtime/stats.c
new file mode 100644 (file)
index 0000000..3a42074
--- /dev/null
@@ -0,0 +1,172 @@
+/* stats.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#include "stats.h"
+#include "bug.h"
+#include "os.h"
+#include "local_state.h"
+
+#include <stdio.h>
+
+#define INVALID_START (0ULL - 1ULL)
+
+#ifdef CILK_PROFILE
+/* MSVC does not support designated initializers, grrrr... */
+static const char *names[] = {
+    /*[INTERVAL_IN_SCHEDULER]*/                 "in scheduler",
+    /*[INTERVAL_WORKING]*/                      "  of which: working",
+    /*[INTERVAL_IN_RUNTIME]*/                   "  of which: in runtime",
+    /*[INTERVAL_STEALING]*/                     "     of which: stealing",
+    /*[INTERVAL_STEAL_SUCCESS]*/                "steal success: detach",
+    /*[INTERVAL_STEAL_FAIL_EMPTYQ]*/            "steal fail: empty queue",
+    /*[INTERVAL_STEAL_FAIL_LOCK]*/              "steal fail: victim locked",
+    /*[INTERVAL_STEAL_FAIL_USER_WORKER]*/       "steal fail: user worker",
+    /*[INTERVAL_STEAL_FAIL_DEKKER]*/            "steal fail: dekker",
+    /*[INTERVAL_SYNC_CHECK]*/                   "sync check",
+    /*[INTERVAL_THE_EXCEPTION_CHECK]*/          "THE exception check",
+    /*[INTERVAL_THE_EXCEPTION_CHECK_USELESS]*/  "  of which: useless",
+    /*[INTERVAL_RETURNING]*/                    "returning",
+    /*[INTERVAL_FINALIZE_CHILD]*/               "finalize child",
+    /*[INTERVAL_PROVABLY_GOOD_STEAL]*/          "provably good steal",
+    /*[INTERVAL_UNCONDITIONAL_STEAL]*/          "unconditional steal",
+    /*[INTERVAL_ALLOC_FULL_FRAME]*/             "alloc full frame",
+    /*[INTERVAL_FRAME_ALLOC_LARGE]*/            "large frame alloc",
+    /*[INTERVAL_FRAME_ALLOC]*/                  "small frame alloc",
+    /*[INTERVAL_FRAME_ALLOC_GLOBAL]*/           "  of which: to global pool",
+    /*[INTERVAL_FRAME_FREE_LARGE]*/             "large frame free",
+    /*[INTERVAL_FRAME_FREE]*/                   "small frame free",
+    /*[INTERVAL_FRAME_FREE_GLOBAL]*/            "  of which: to global pool",
+    /*[INTERVAL_MUTEX_LOCK]*/                   "mutex lock",
+    /*[INTERVAL_MUTEX_LOCK_SPINNING]*/          "  spinning",
+    /*[INTERVAL_MUTEX_LOCK_YIELDING]*/          "  yielding",
+    /*[INTERVAL_MUTEX_TRYLOCK]*/                "mutex trylock",
+    /*[INTERVAL_FIBER_ALLOCATE]*/               "fiber_allocate",
+    /*[INTERVAL_FIBER_DEALLOCATE]*/             "fiber_deallocate", 
+    /*[INTERVAL_FIBER_ALLOCATE_FROM_THREAD]*/   "fiber_allocate_from_thread",
+    /*[INTERVAL_FIBER_DEALLOCATE_FROM_THREAD]*/ "fiber_deallocate (thread)", 
+    /*[INTERVAL_SUSPEND_RESUME_OTHER]*/         "fiber suspend self + resume",
+    /*[INTERVAL_DEALLOCATE_RESUME_OTHER]*/      "fiber deallocate self + resume", 
+};
+#endif
+
+void __cilkrts_init_stats(statistics *s)
+{
+    int i;
+    for (i = 0; i < INTERVAL_N; ++i) {
+        s->start[i] = INVALID_START;
+        s->accum[i] = 0;
+        s->count[i] = 0;
+    }
+
+    s->stack_hwm = 0;
+}
+
+#ifdef CILK_PROFILE
+void __cilkrts_accum_stats(statistics *to, statistics *from)
+{
+    int i;
+
+    for (i = 0; i < INTERVAL_N; ++i) {
+        to->accum[i] += from->accum[i];
+        to->count[i] += from->count[i];
+        from->accum[i] = 0;
+        from->count[i] = 0;
+    }
+
+    if (from->stack_hwm > to->stack_hwm)
+        to->stack_hwm = from->stack_hwm;
+    from->stack_hwm = 0;
+}
+
+void __cilkrts_note_interval(__cilkrts_worker *w, enum interval i)
+{
+    if (w) {
+        statistics *s = w->l->stats;
+        CILK_ASSERT(s->start[i] == INVALID_START);
+        s->count[i]++;
+    }
+}
+
+void __cilkrts_start_interval(__cilkrts_worker *w, enum interval i)
+{
+    if (w) {
+        statistics *s = w->l->stats;
+        CILK_ASSERT(s->start[i] == INVALID_START);
+        s->start[i] = __cilkrts_getticks();
+        s->count[i]++;
+    }
+}
+
+void __cilkrts_stop_interval(__cilkrts_worker *w, enum interval i)
+{
+    if (w) {
+        statistics *s = w->l->stats;
+        CILK_ASSERT(s->start[i] != INVALID_START);
+        s->accum[i] += __cilkrts_getticks() - s->start[i];
+        s->start[i] = INVALID_START;
+    }
+}
+
+void dump_stats_to_file(FILE *stat_file, statistics *s)
+{
+    int i;
+    fprintf(stat_file, "\nCILK PLUS RUNTIME SYSTEM STATISTICS:\n\n");
+
+    fprintf(stat_file,
+            "  %-32s: %15s %10s %12s %10s\n",
+            "event",
+            "count",
+            "ticks",
+            "ticks/count",
+            "%total"
+        );
+    for (i = 0; i < INTERVAL_N; ++i) {
+        fprintf(stat_file, "  %-32s: %15llu", names[i], s->count[i]);
+        if (s->accum[i]) {
+            fprintf(stat_file, " %10.3g %12.3g %10.2f",
+                    (double)s->accum[i],
+                    (double)s->accum[i] / (double)s->count[i],
+                    100.0 * (double)s->accum[i] / 
+                    (double)s->accum[INTERVAL_IN_SCHEDULER]);
+        }
+        fprintf(stat_file, "\n");
+    }
+}
+#endif // CILK_PROFILE
+
+/* End stats.c */
diff --git a/libcilkrts/runtime/stats.h b/libcilkrts/runtime/stats.h
new file mode 100644 (file)
index 0000000..aaa9927
--- /dev/null
@@ -0,0 +1,208 @@
+/* stats.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file stats.h
+ *
+ * @brief Support for gathering and reporting statistics on Cilk applications.
+ *
+ * Note that stats are normally NOT compiled in because it increases the
+ * overhead of stealing.  To compile in profiling support, define CILK_PROFILE.
+ */
+
+#ifndef INCLUDED_STATS_DOT_H
+#define INCLUDED_STATS_DOT_H
+
+/* #define CILK_PROFILE 1 */
+// @note  The CILK_PROFILE flag and intervals is known to be broken
+//        in at least programs with Windows exceptions. 
+//        Enable this flag at your own peril. :)
+
+#include <cilk/common.h>
+#include "rts-common.h"
+#include "internal/abi.h"
+
+#ifdef CILK_PROFILE
+#include <stdio.h>     // Define FILE *
+#endif
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/** @brief Events that we measure. */
+enum interval
+{
+    INTERVAL_IN_SCHEDULER,                  ///< Time threads spend "bound" to Cilk
+    INTERVAL_WORKING,                       ///< Time spent working
+    INTERVAL_IN_RUNTIME,                    ///< Time spent executing runtime scheduling loop
+    INTERVAL_STEALING,                      ///< Time spent stealing work
+    INTERVAL_STEAL_SUCCESS,                 ///< Time to do a successful steal
+    INTERVAL_STEAL_FAIL_EMPTYQ,             ///< Count of steal failures due to lack of stealable work
+    INTERVAL_STEAL_FAIL_LOCK,               ///< Count of steal failures due to failure to lock worker
+    INTERVAL_STEAL_FAIL_USER_WORKER,        ///< Count of steal failures by user workers which attempt to steal from another team
+    INTERVAL_STEAL_FAIL_DEKKER,             ///< Count of steal failures due to Dekker protocol failure
+    INTERVAL_SYNC_CHECK,                    ///< Time spent processing syncs
+    INTERVAL_THE_EXCEPTION_CHECK,           ///< Time spent performing THE exception checks
+    INTERVAL_THE_EXCEPTION_CHECK_USELESS,   ///< Count of useless THE exception checks
+    INTERVAL_RETURNING,                     ///< Time spent returning from calls
+    INTERVAL_FINALIZE_CHILD,                ///< Time spent in finalize_child
+    INTERVAL_PROVABLY_GOOD_STEAL,           ///< Time spent in provably_good_steal
+    INTERVAL_UNCONDITIONAL_STEAL,           ///< Time spent in unconditional_steal
+    INTERVAL_ALLOC_FULL_FRAME,              ///< Time spent in __cilkrts_make_full_frame
+    INTERVAL_FRAME_ALLOC_LARGE,             ///< Count of calls to __cilkrts_frame_malloc for buffers bigger than FRAME_MALLOC_MAX_SIZE or with a NULL worker
+    INTERVAL_FRAME_ALLOC,                   ///< Time spent allocating memory from worker buckets
+    INTERVAL_FRAME_ALLOC_GLOBAL,            ///< Time spent calling memory allocator when buckets are empty
+    INTERVAL_FRAME_FREE_LARGE,              ///< Count of calls to __cilkrts_frame_malloc for buffers bigger than FRAME_MALLOC_MAX_SIZE or with a NULL worker
+    INTERVAL_FRAME_FREE,                    ///< Time spent freeing memory to worker buckets
+    INTERVAL_FRAME_FREE_GLOBAL,             ///< Time spent calling memory deallocator when buckets are full
+    INTERVAL_MUTEX_LOCK,                    ///< Count of calls to __cilkrts_mutex_lock for a worker
+    INTERVAL_MUTEX_LOCK_SPINNING,           ///< Time spent spinning in __cilkrts_mutex_lock for a worker
+    INTERVAL_MUTEX_LOCK_YIELDING,           ///< Time spent yielding in __cilkrts_mutex_lock for a worker
+    INTERVAL_MUTEX_TRYLOCK,                 ///< Count of calls to __cilkrts_mutex_trylock
+    INTERVAL_FIBER_ALLOCATE,                ///< Time spent calling cilk_fiber_allocate
+    INTERVAL_FIBER_DEALLOCATE,              ///< Time spent calling cilk_fiber_deallocate (not from thread)
+    INTERVAL_FIBER_ALLOCATE_FROM_THREAD,    ///< Time spent calling cilk_fiber_allocate_from_thread
+    INTERVAL_FIBER_DEALLOCATE_FROM_THREAD,  ///< Time spent calling cilk_fiber_deallocate (from thread)
+    INTERVAL_SUSPEND_RESUME_OTHER,          ///< Count of fiber suspend_self_and_resume_other
+    INTERVAL_DEALLOCATE_RESUME_OTHER,       ///< Count of fiber deallocate_self_and_resume_other
+    INTERVAL_N                              ///< Number of intervals, must be last
+};
+
+/**
+ * @brief Struct that collects of all runtime statistics.
+ * 
+ * There is an instance of this structure in each worker's
+ * local_state, as well as one in the @c global_state_t which will be
+ * used to accumulate the per-worker stats.
+ */
+typedef struct statistics
+{
+    /** Number of times each interval is entered */
+    unsigned long long count[INTERVAL_N];
+
+    /**
+     * Time when the system entered each interval, in system-dependent
+     * "ticks"
+     */
+    unsigned long long start[INTERVAL_N];
+
+    /** Total time spent in each interval, in system-dependent "ticks" */
+    unsigned long long accum[INTERVAL_N];
+
+    /**
+     * Largest global number of stacks seen by this worker.
+     * The true maximum at end of execution is the max of the
+     * worker maxima.
+     */
+    long stack_hwm;
+} statistics;
+
+/**
+ * Initializes a statistics structure
+ *
+ * @param s The statistics structure to be initialized.
+ */
+COMMON_PORTABLE void __cilkrts_init_stats(statistics *s);
+
+/**
+ * @brief Sums statistics from worker to the global struct
+ *
+ * @param to   The statistics structure that will accumulate the information.
+ *             This structure is usually @c g->stats.
+ * @param from The statistics structure that will be accumulated.
+ *             This structure is usually statistics kept per worker.
+ */
+COMMON_PORTABLE
+void __cilkrts_accum_stats(statistics *to, statistics *from);
+
+/**
+ * @brief Mark the start of an interval by saving the current tick count.
+ *
+ * @pre Start time == INVALID_START
+ *
+ * @param w The worker we're accumulating stats for.
+ * @param i The interval we're accumulating stats for.
+ */
+COMMON_PORTABLE
+void __cilkrts_start_interval(__cilkrts_worker *w, enum interval i);
+
+/**
+ * @brief Mark the end of an interval by adding the ticks since the
+ * start to the accumulated time.
+ *
+ * @pre Start time != INVALID_START
+ *
+ * @param w The worker we're accumulating stats for.
+ * @param i The interval we're accumulating stats for.
+ */
+COMMON_PORTABLE
+void __cilkrts_stop_interval(__cilkrts_worker *w, enum interval i);
+
+/**
+ * @brief Start and stop interval I, charging zero time against it
+ *
+ * Precondition:
+ * - Start time == INVALID_START
+ *
+ * @param w The worker we're accumulating stats for.
+ * @param i The interval we're accumulating stats for.
+ */
+COMMON_PORTABLE
+void __cilkrts_note_interval(__cilkrts_worker *w, enum interval i);
+
+#ifdef CILK_PROFILE
+COMMON_PORTABLE
+void dump_stats_to_file(FILE *stat_file, statistics *s);
+#endif
+
+
+#ifdef CILK_PROFILE
+# define START_INTERVAL(w, i) __cilkrts_start_interval(w, i);
+# define STOP_INTERVAL(w, i) __cilkrts_stop_interval(w, i);
+# define NOTE_INTERVAL(w, i) __cilkrts_note_interval(w, i);
+#else
+/** Start an interval.  No effect unless CILK_PROFILE is defined. */
+# define START_INTERVAL(w, i)
+/** End an interval.  No effect unless CILK_PROFILE is defined. */
+# define STOP_INTERVAL(w, i)
+/** Increment a counter.  No effect unless CILK_PROFILE is defined. */
+# define NOTE_INTERVAL(w, i)
+#endif
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_STATS_DOT_H)
diff --git a/libcilkrts/runtime/symbol_test.c b/libcilkrts/runtime/symbol_test.c
new file mode 100644 (file)
index 0000000..1113ecd
--- /dev/null
@@ -0,0 +1,62 @@
+/* symbol_test.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/* simple program to verify that there are no undefined symbols in the runtime.
+ * If the runtime uses any symbols that are not defined, compiling this program
+ * will cause a linker error.
+ */
+
+extern void* __cilkrts_global_state;
+void *volatile p;
+
+void foo () { }
+int main ()
+{
+    int i;
+    long long j;
+
+    _Cilk_spawn foo();
+    _Cilk_for (i = 0; i < 2; ++i)
+        foo();
+    _Cilk_for (j = 0; j < 2; ++j)
+        foo();
+    p = __cilkrts_global_state;
+    return 0;
+}
+
+/* End symbol_test.c */
diff --git a/libcilkrts/runtime/sysdep-unix.c b/libcilkrts/runtime/sysdep-unix.c
new file mode 100644 (file)
index 0000000..194681f
--- /dev/null
@@ -0,0 +1,794 @@
+/*
+ * sysdep-unix.c
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2010-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************
+ */
+
+#ifdef __linux__
+    // define _GNU_SOURCE before *any* #include.
+    // Even <stdint.h> will break later #includes if this macro is not
+    // already defined when it is #included.
+#   define _GNU_SOURCE
+#endif
+
+#include "sysdep.h"
+#include "os.h"
+#include "bug.h"
+#include "local_state.h"
+#include "signal_node.h"
+#include "full_frame.h"
+#include "jmpbuf.h"
+#include "cilk_malloc.h"
+#include "reducer_impl.h"
+#include "metacall_impl.h"
+
+
+// On x86 processors (but not MIC processors), the compiler generated code to
+// save the FP state (rounding mode and the like) before calling setjmp.  We
+// will need to restore that state when we resume.
+#ifndef __MIC__
+# if defined(__i386__) || defined(__x86_64)
+#   define RESTORE_X86_FP_STATE
+# endif // defined(__i386__) || defined(__x86_64)
+#endif  // __MIC__
+
+// contains notification macros for VTune.
+#include "cilk-ittnotify.h"
+
+#include <stddef.h>
+
+#ifdef __CYGWIN__
+// On Cygwin, string.h doesnt declare strcasecmp if __STRICT_ANSI__ is defined
+#   undef __STRICT_ANSI__
+#endif
+
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <alloca.h>
+
+#ifdef __APPLE__
+//#   include <scheduler.h>  // Angle brackets include Apple's scheduler.h, not ours.
+#endif
+
+#ifdef __linux__
+#   include <sys/resource.h>
+#   include <sys/sysinfo.h>
+#endif
+
+#ifdef __FreeBSD__
+#   include <sys/resource.h>
+// BSD does not define MAP_ANONYMOUS, but *does* define MAP_ANON. Aren't standards great!
+#   define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#ifdef  __VXWORKS__
+#   include <vxWorks.h>   
+#   include <vxCpuLib.h>  
+#endif
+
+struct global_sysdep_state
+{
+    pthread_t *threads;    ///< Array of pthreads for system workers
+    size_t pthread_t_size; ///< for cilk_db
+}; 
+
+static void internal_enforce_global_visibility();
+
+
+COMMON_SYSDEP
+void __cilkrts_init_worker_sysdep(struct __cilkrts_worker *w)
+{
+    ITT_SYNC_CREATE(w, "Scheduler");
+}
+
+COMMON_SYSDEP
+void __cilkrts_destroy_worker_sysdep(struct __cilkrts_worker *w)
+{
+}
+
+COMMON_SYSDEP
+void __cilkrts_init_global_sysdep(global_state_t *g)
+{
+    internal_enforce_global_visibility();
+
+    __cilkrts_init_tls_variables();
+
+    CILK_ASSERT(g->total_workers >= g->P - 1);
+    g->sysdep = __cilkrts_malloc(sizeof (struct global_sysdep_state));
+    CILK_ASSERT(g->sysdep);
+    g->sysdep->pthread_t_size = sizeof (pthread_t);
+    
+    // TBD: Should this value be g->total_workers, or g->P?
+    //      Need to check what we are using this field for.
+    g->sysdep->threads = __cilkrts_malloc(sizeof(pthread_t) * g->total_workers);
+    CILK_ASSERT(g->sysdep->threads);
+
+    return;
+}
+
+COMMON_SYSDEP
+void __cilkrts_destroy_global_sysdep(global_state_t *g)
+{
+    if (g->sysdep->threads)
+        __cilkrts_free(g->sysdep->threads);
+    __cilkrts_free(g->sysdep);
+}
+
+/*************************************************************
+  Creation of worker threads:
+*************************************************************/
+
+static void internal_run_scheduler_with_exceptions(__cilkrts_worker *w)
+{
+    /* We assume the stack grows down. */
+    char var;
+    __cilkrts_cilkscreen_establish_c_stack(&var - 1000000, &var);
+
+    __cilkrts_run_scheduler_with_exceptions(w);
+}
+
+
+
+/*
+ * scheduler_thread_proc_for_system_worker
+ *
+ * Thread start function called when we start a new worker.
+ *
+ */
+NON_COMMON void* scheduler_thread_proc_for_system_worker(void *arg)
+{
+    /*int status;*/
+    __cilkrts_worker *w = (__cilkrts_worker *)arg;
+
+#ifdef __INTEL_COMPILER
+#ifdef USE_ITTNOTIFY
+    // Name the threads for Advisor.  They don't want a worker number.
+    __itt_thread_set_name("Cilk Worker");
+#endif // defined USE_ITTNOTIFY
+#endif // defined __INTEL_COMPILER
+
+    /* Worker startup is serialized
+    status = pthread_mutex_lock(&__cilkrts_global_mutex);
+    CILK_ASSERT(status == 0);*/
+    CILK_ASSERT(w->l->type == WORKER_SYSTEM);
+    /*status = pthread_mutex_unlock(&__cilkrts_global_mutex);
+    CILK_ASSERT(status == 0);*/
+    
+    __cilkrts_set_tls_worker(w);
+
+    // Create a cilk fiber for this worker on this thread.
+    START_INTERVAL(w, INTERVAL_FIBER_ALLOCATE_FROM_THREAD) {
+        w->l->scheduling_fiber = cilk_fiber_allocate_from_thread();
+        cilk_fiber_set_owner(w->l->scheduling_fiber, w);
+    } STOP_INTERVAL(w, INTERVAL_FIBER_ALLOCATE_FROM_THREAD);
+    
+    internal_run_scheduler_with_exceptions(w);
+
+    START_INTERVAL(w, INTERVAL_FIBER_DEALLOCATE_FROM_THREAD) {
+        // Deallocate the scheduling fiber.  This operation reverses the
+        // effect cilk_fiber_allocate_from_thread() and must be done in this
+        // thread before it exits.
+        int ref_count = cilk_fiber_deallocate_from_thread(w->l->scheduling_fiber);
+        // Scheduling fibers should never have extra references to them.
+        // We only get extra references into fibers because of Windows
+        // exceptions.
+        CILK_ASSERT(0 == ref_count);
+        w->l->scheduling_fiber = NULL;
+    } STOP_INTERVAL(w, INTERVAL_FIBER_DEALLOCATE_FROM_THREAD);
+    
+    return 0;
+}
+
+
+/*
+ * __cilkrts_user_worker_scheduling_stub
+ *
+ * Routine for the scheduling fiber created for an imported user
+ * worker thread.  This method is analogous to
+ * scheduler_thread_proc_for_system_worker.
+ *
+ */
+void __cilkrts_user_worker_scheduling_stub(cilk_fiber* fiber, void* null_arg)
+{
+    __cilkrts_worker *w = __cilkrts_get_tls_worker();
+
+    // Sanity check.
+    CILK_ASSERT(WORKER_USER == w->l->type);
+
+    // Enter the scheduling loop on the user worker.
+    // This function will never return.
+    __cilkrts_run_scheduler_with_exceptions(w);
+
+    // A WORKER_USER, at some point, will resume on the original stack and leave
+    // Cilk.  Under no circumstances do we ever exit off of the bottom of this
+    // stack.
+    CILK_ASSERT(0);
+}
+
+/**
+ * We are exporting a function with this name to Inspector?
+ * What a confusing name...
+ *
+ * This function is exported so Piersol's stack trace displays
+ * reasonable information.
+ */ 
+void* __cilkrts_worker_stub(void* arg)
+{
+    return scheduler_thread_proc_for_system_worker(arg);
+}
+
+
+
+// /* Return the lesser of the argument and the operating system
+//    limit on the number of workers (threads) that may or ought
+//    to be created. */
+// int sysdep_thread_limit(int n, int physical_cpus)
+// {
+//     /* On Linux thread creation fails somewhere short of the
+//        number of available processes. */
+//     struct rlimit lim;
+
+//     if (n > 256 + 2 * physical_cpus)
+//         n = 256 + 2 * physical_cpus;
+
+//     if (getrlimit(RLIMIT_NPROC, &lim) == 0 && lim.rlim_cur != RLIM_INFINITY)
+//     {
+//         /* If the limit reads 0 or absurdly small, ignore it. */
+//         unsigned int maxproc = (lim.rlim_cur * 3 + 3) / 4;
+//         if (maxproc > 8 + 2 * physical_cpus && maxproc < n)
+//             n = maxproc;
+//     }
+//     return n;
+// }
+
+
+
+static void write_version_file (global_state_t *, int);
+
+/* Create n worker threads from base..top-1
+ */
+static void create_threads(global_state_t *g, int base, int top)
+{
+    // TBD(11/30/12): We want to insert code providing the option of
+    // pinning system workers to cores.
+    for (int i = base; i < top; i++) {
+        int status = pthread_create(&g->sysdep->threads[i],
+                                    NULL,
+                                    scheduler_thread_proc_for_system_worker,
+                                    g->workers[i]);
+        if (status != 0)
+            __cilkrts_bug("Cilk runtime error: thread creation (%d) failed: %d\n", i, status);
+    }
+}
+
+#if PARALLEL_THREAD_CREATE
+static int volatile threads_created = 0;
+
+// Create approximately half of the worker threads, and then become a worker
+// ourselves.
+static void * create_threads_and_work (void * arg)
+{
+    global_state_t *g = ((__cilkrts_worker *)arg)->g;
+
+    create_threads(g, g->P/2, g->P-1);
+    // Let the initial thread know that we're done.
+    threads_created = 1;
+
+    // Ideally this turns into a tail call that wipes out this stack frame.
+    return scheduler_thread_proc_for_system_worker(arg);
+}
+#endif
+void __cilkrts_start_workers(global_state_t *g, int n)
+{
+    g->workers_running = 1;
+    g->work_done = 0;
+
+    if (!g->sysdep->threads)
+        return;
+
+    // Do we actually have any threads to create?
+    if (n > 0)
+    {
+#if PARALLEL_THREAD_CREATE
+            int status;
+            // We create (a rounded up) half of the threads, thread one creates the rest
+            int half_threads = (n+1)/2;
+        
+            // Create the first thread passing a different thread function, so that it creates threads itself
+            status = pthread_create(&g->sysdep->threads[0], NULL, create_threads_and_work, g->workers[0]);
+
+            if (status != 0)
+                __cilkrts_bug("Cilk runtime error: thread creation (0) failed: %d\n", status);
+            
+            // Then the rest of the ones we have to create
+            create_threads(g, 1, half_threads);
+
+            // Now wait for the first created thread to tell us it's created all of its threads.
+            // We could maybe drop this a bit lower and overlap with write_version_file.
+            while (!threads_created)
+                __cilkrts_yield();
+#else
+            // Simply create all the threads linearly here.
+            create_threads(g, 0, n);
+#endif
+    }
+    // write the version information to a file if the environment is configured
+    // for it (the function makes the check).
+    write_version_file(g, n);
+
+
+    return;
+}
+
+void __cilkrts_stop_workers(global_state_t *g)
+{
+    int i;
+
+    // Tell the workers to give up
+
+    g->work_done = 1;
+
+    if (g->workers_running == 0)
+        return;
+
+    if (!g->sysdep->threads)
+        return;
+
+    /* Make them all runnable. */
+    if (g->P > 1) {
+        CILK_ASSERT(g->workers[0]->l->signal_node);
+        signal_node_msg(g->workers[0]->l->signal_node, 1);
+    }
+
+        for (i = 0; i < g->P - 1; ++i) {
+            int sc_status;
+            void *th_status;
+
+            sc_status = pthread_join(g->sysdep->threads[i], &th_status);
+            if (sc_status != 0)
+                __cilkrts_bug("Cilk runtime error: thread join (%d) failed: %d\n", i, sc_status);
+        }
+
+    g->workers_running = 0;
+
+
+    return;
+}
+
+
+/*
+ * @brief Returns the stack address for resuming execution of sf.
+ *
+ * This method takes in the top of the stack to use, and then returns
+ * a properly aligned address for resuming execution of sf.
+ *
+ *  @param sf           -   The stack frame we want to resume executing.
+ *  @param stack_base   -   The top of the stack we want to execute sf on.
+ *
+ */
+static char* get_sp_for_executing_sf(char* stack_base,
+                                     full_frame *ff,
+                                     __cilkrts_stack_frame *sf)
+{
+// The original calculation that had been done to correct the stack
+// pointer when resuming execution.
+//
+// But this code was never getting called in the eng branch anyway...
+// 
+// TBD(11/30/12): This logic needs to be revisited to make sure that
+// we are doing the proper calculation in reserving space for outgoing
+// arguments on all platforms and architectures.
+#if 0    
+    /* Preserve outgoing argument space and stack alignment on steal.
+       Outgoing argument space is bounded by the difference between
+       stack and frame pointers.  Some user code is known to rely on
+       16 byte alignment.  Maintain 32 byte alignment for future
+       compatibility. */
+#define SMASK 31 /* 32 byte alignment */
+    if (sf) {
+        char *fp = FP(sf), *sp = SP(sf);
+        int fp_align = (int)(size_t)fp & SMASK;
+        ptrdiff_t space = fp - sp;
+
+        fprintf(stderr, "Here: fp = %p, sp = %p\n", fp, sp);
+        char *top_aligned = (char *)((((size_t)stack_base - SMASK) & ~(size_t)SMASK) | fp_align);
+        /* Don't allocate an unreasonable amount of stack space. */
+
+        fprintf(stderr, "Here: stack_base = %p, top_aligned=%p, space=%ld\n",
+                stack_base, top_aligned, space);
+        if (space < 32)
+            space = 32 + (space & SMASK);
+        else if (space > 40 * 1024)
+            space = 40 * 1024 + (space & SMASK);
+
+        return top_aligned - space;
+    }
+#endif    
+
+#define PERFORM_FRAME_SIZE_CALCULATION 0
+    
+    char* new_stack_base = stack_base - 256;
+
+#if PERFORM_FRAME_SIZE_CALCULATION
+    // If there is a frame size saved, then use that as the
+    // correction instead of 256.
+    if (ff->frame_size > 0) {
+        if (ff->frame_size < 40*1024) {
+            new_stack_base = stack_base - ff->frame_size;
+        }
+        else {
+            // If for some reason, our frame size calculation is giving us
+            // a number which is bigger than about 10 pages, then
+            // there is likely something wrong here?  Don't allocate
+            // an unreasonable amount of space.
+            new_stack_base = stack_base - 40*1024;
+        }
+    }
+#endif
+    
+    // Whatever correction we choose, align the final stack top.
+    // This alignment seems to be necessary in particular on 32-bit
+    // Linux, and possibly Mac. (Is 32-byte alignment is sufficient?)
+    /* 256-byte alignment. Why not? */
+    const uintptr_t align_mask = ~(256 -1);
+    new_stack_base = (char*)((size_t)new_stack_base & align_mask);
+    return new_stack_base;
+}
+
+char* sysdep_reset_jump_buffers_for_resume(cilk_fiber* fiber,
+                                           full_frame *ff,
+                                           __cilkrts_stack_frame *sf)
+{
+#if FIBER_DEBUG >= 4
+    fprintf(stderr, "ThreadId=%p (fiber_proc_to_resume), Fiber %p.  sf = %p. ff=%p, ff->sync_sp=%p\n",
+            cilkos_get_current_thread_id(),
+            fiber,
+            sf,
+            ff, ff->sync_sp);
+#endif
+
+    CILK_ASSERT(fiber);
+    void* sp = (void*)get_sp_for_executing_sf(cilk_fiber_get_stack_base(fiber), ff, sf);
+    SP(sf) = sp;
+
+    /* Debugging: make sure stack is accessible. */
+    ((volatile char *)sp)[-1];
+
+    // Adjust the saved_sp to account for the SP we're about to run.  This will
+    // allow us to track fluctations in the stack
+#if FIBER_DEBUG >= 4    
+    fprintf(stderr, "ThreadId=%p, about to take stack ff=%p, sp=%p, sync_sp=%p\n",
+            cilkos_get_current_thread_id(),
+            ff,
+            sp,
+            ff->sync_sp);
+#endif
+    __cilkrts_take_stack(ff, sp);
+    return sp;
+}
+
+
+NORETURN sysdep_longjmp_to_sf(char* new_sp,
+                              __cilkrts_stack_frame *sf,
+                              full_frame *ff_for_exceptions /* UNUSED on Unix */)
+{
+#if FIBER_DEBUG >= 3
+    fprintf(stderr,
+            "ThreadId=%p. resume user code, sf=%p, new_sp = %p, original SP(sf) = %p, FP(sf) = %p\n",
+            cilkos_get_current_thread_id(), sf, new_sp, SP(sf), FP(sf));
+#endif
+
+    // Set the stack pointer.
+    SP(sf) = new_sp;
+
+#ifdef RESTORE_X86_FP_STATE
+    if (CILK_FRAME_VERSION_VALUE(sf->flags) >= 1) {
+        // Restore the floating point state that was set in this frame at the
+        // last spawn.
+        //
+        // This feature is only available in ABI 1 or later frames, and only
+        // needed on IA64 or Intel64 processors.
+        restore_x86_fp_state(sf);
+    }
+#endif
+
+    CILK_LONGJMP(sf->ctx);
+}
+
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <errno.h>
+
+
+void __cilkrts_make_unrunnable_sysdep(__cilkrts_worker *w,
+                                      full_frame *ff,
+                                      __cilkrts_stack_frame *sf,
+                                      int is_loot,
+                                      const char *why)
+{
+    (void)w; /* unused */
+    sf->except_data = 0;
+
+    if (is_loot)
+    {
+        if (ff->frame_size == 0)
+        ff->frame_size = __cilkrts_get_frame_size(sf);
+
+        // Null loot's sp for debugging purposes (so we'll know it's not valid)
+    SP(sf) = 0;
+    }
+}
+
+/*
+ * __cilkrts_sysdep_is_worker_thread_id
+ *
+ * Returns true if the thread ID specified matches the thread ID we saved
+ * for a worker.
+ */
+
+int __cilkrts_sysdep_is_worker_thread_id(global_state_t *g,
+                                         int i,
+                                         void *thread_id)
+{
+#if defined( __linux__) || defined(__VXWORKS__)
+    pthread_t tid = *(pthread_t *)thread_id;
+    if (i < 0 || i > g->total_workers)
+        return 0;
+    return g->sysdep->threads[i] == tid;
+#else
+    // Needs to be implemented
+    return 0;
+#endif
+}
+
+
+
+
+/*************************************************************
+  Version information:
+*************************************************************/
+
+#include <dlfcn.h>
+#include "internal/cilk_version.h"
+#include <stdio.h>
+#include <sys/utsname.h>
+
+#ifdef __VXWORKS__
+#include <version.h>
+# endif
+
+/* (Non-static) dummy function is used by get_runtime_path() to find the path
+ * to the .so containing the Cilk runtime.
+ */
+void dummy_function() { }
+
+/* return a string with the path to the Cilk runtime, or "unknown" if the path
+ * cannot be determined.
+ */
+static const char *get_runtime_path ()
+{
+#ifdef __CYGWIN__
+    // Cygwin doesn't support dladdr, which sucks
+    return "unknown";
+#else
+    Dl_info info;
+    if (0 == dladdr(dummy_function, &info)) return "unknown";
+    return info.dli_fname;
+#endif
+}
+
+/* if the environment variable, CILK_VERSION, is defined, writes the version
+ * information to the specified file.
+ * g is the global state that was just created, and n is the number of workers
+ * that were made (or requested from RML) for it.
+ */
+static void write_version_file (global_state_t *g, int n)
+{
+    const char *env;      // environment variable.
+    char buf[256];        // print buffer.
+    time_t t;
+    FILE *fp;
+    struct utsname sys_info;
+    int err;              // error code from system calls.
+
+    // if CILK_VERSION is not set, or if the file cannot be opened, fail
+    // silently.  Otherwise open the file for writing (or use stderr or stdout
+    // if the user specifies).
+    if (NULL == (env = getenv("CILK_VERSION"))) return;
+    if (0 == strcasecmp(env, "stderr"))         fp = stderr;
+    else if (0 == strcasecmp(env, "stdout"))    fp = stdout;
+    else if (NULL == (fp = fopen(env, "w")))    return;
+
+    // get a string for the current time.  E.g.,
+    // Cilk runtime initialized: Thu Jun 10 13:28:00 2010
+    t = time(NULL);
+    strftime(buf, 256, "%a %b %d %H:%M:%S %Y", localtime(&t));
+    fprintf(fp, "Cilk runtime initialized: %s\n", buf);
+
+    // Print runtime info.  E.g.,
+    // Cilk runtime information
+    // ========================
+    // Cilk version: 2.0.0 Build 9184
+    // Built by willtor on host willtor-desktop
+    // Compilation date: Thu Jun 10 13:27:42 2010
+    // Compiled with ICC V99.9.9, ICC build date: 20100610
+
+    fprintf(fp, "\nCilk runtime information\n");
+    fprintf(fp, "========================\n");
+    fprintf(fp, "Cilk version: %d.%d.%d Build %d\n",
+            VERSION_MAJOR,
+            VERSION_MINOR,
+            VERSION_REV,
+            VERSION_BUILD);
+#ifdef __VXWORKS__    
+    char * vxWorksVer = VXWORKS_VERSION; 
+    fprintf(fp, "Cross compiled for %s\n",vxWorksVer);
+    // user and host not avalible if VxWorks cross compiled on windows build host 
+#else
+
+    // User and host are not available for GCC builds
+#ifdef BUILD_USER
+    fprintf(fp, "Built by "BUILD_USER" on host "BUILD_HOST"\n");
+#endif // BUILD_USER
+#endif // __VXWORKS__
+
+    // GCC has requested that this be removed for GCC builds
+#ifdef BUILD_USER    
+    fprintf(fp, "Compilation date: "__DATE__" "__TIME__"\n");
+#endif // BUILD_USER
+
+#ifdef __INTEL_COMPILER
+    // Compiled by the Intel C/C++ compiler.
+    fprintf(fp, "Compiled with ICC V%d.%d.%d, ICC build date: %d\n",
+            __INTEL_COMPILER / 100,
+            (__INTEL_COMPILER / 10) % 10,
+            __INTEL_COMPILER % 10,
+            __INTEL_COMPILER_BUILD_DATE);
+#else
+    // Compiled by GCC.
+    fprintf(fp, "Compiled with GCC V%d.%d.%d\n",
+            __GNUC__,
+            __GNUC_MINOR__,
+            __GNUC_PATCHLEVEL__);
+#endif // defined __INTEL_COMPILER
+
+    // Print system info.  E.g.,
+    // System information
+    // ==================
+    // Cilk runtime path: /opt/icc/64/lib/libcilkrts.so.5
+    // System OS: Linux, release 2.6.28-19-generic
+    // System architecture: x86_64
+
+    err = uname(&sys_info);
+    fprintf(fp, "\nSystem information\n");
+    fprintf(fp, "==================\n");
+    fprintf(fp, "Cilk runtime path: %s\n", get_runtime_path());
+    fprintf(fp, "System OS: %s, release %s\n",
+            err < 0 ? "unknown" : sys_info.sysname,
+            err < 0 ? "?" : sys_info.release);
+    fprintf(fp, "System architecture: %s\n",
+            err < 0 ? "unknown" : sys_info.machine);
+
+    // Print thread info.  E.g.,
+    // Thread information
+    // ==================
+    // System cores: 8
+    // Cilk workers requested: 8
+    // Thread creator: Private
+
+    fprintf(fp, "\nThread information\n");
+    fprintf(fp, "==================\n");
+#ifdef __VXWORKS__      
+    fprintf(fp, "System cores: %d\n", (int)__builtin_popcount(vxCpuEnabledGet()));
+#else    
+    fprintf(fp, "System cores: %d\n", (int)sysconf(_SC_NPROCESSORS_ONLN));
+#endif    
+    fprintf(fp, "Cilk workers requested: %d\n", n);
+#if (PARALLEL_THREAD_CREATE)
+        fprintf(fp, "Thread creator: Private (parallel)\n");
+#else
+        fprintf(fp, "Thread creator: Private\n");
+#endif
+
+    if (fp != stderr && fp != stdout) fclose(fp);
+    else fflush(fp); // flush the handle buffer if it is stdout or stderr.
+}
+
+
+/*
+ * __cilkrts_establish_c_stack
+ *
+ * Tell Cilkscreen about the user stack bounds.
+ *
+ * Note that the Cilk V1 runtime only included the portion of the stack from
+ * the entry into Cilk, down.  We don't appear to be able to find that, but
+ * I think this will be sufficient.
+ */
+
+void __cilkrts_establish_c_stack(void)
+{
+    /* FIXME: Not implemented. */
+
+    /* TBD: Do we need this */
+    /*
+    void __cilkrts_cilkscreen_establish_c_stack(char *begin, char *end);
+
+    size_t r;
+    MEMORY_BASIC_INFORMATION mbi;
+
+    r = VirtualQuery (&mbi,
+                      &mbi,
+                      sizeof(mbi));
+
+    __cilkrts_cilkscreen_establish_c_stack((char *)mbi.BaseAddress,
+                                   (char *)mbi.BaseAddress + mbi.RegionSize);
+    */
+}
+
+
+/*
+ * internal_enforce_global_visibility
+ *
+ * Ensure global visibility of public symbols, for proper Cilk-TBB interop.
+ *
+ * If Cilk runtime is loaded dynamically, its symbols might remain unavailable
+ * for global search with dladdr; that might prevent TBB from finding Cilk
+ * in the process address space and initiating the interop protocol.
+ * The workaround is for the library to open itself with RTLD_GLOBAL flag.
+ */
+
+static __attribute__((noinline))
+void internal_enforce_global_visibility()
+{
+    void* handle = dlopen( get_runtime_path(), RTLD_GLOBAL|RTLD_LAZY );
+
+    /* For proper reference counting, close the handle immediately. */
+    if( handle) dlclose(handle);
+}
+
+/*
+  Local Variables: **
+  c-file-style:"bsd" **
+  c-basic-offset:4 **
+  indent-tabs-mode:nil **
+  End: **
+*/
diff --git a/libcilkrts/runtime/sysdep.h b/libcilkrts/runtime/sysdep.h
new file mode 100644 (file)
index 0000000..ea939ac
--- /dev/null
@@ -0,0 +1,285 @@
+/* sysdep.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file sysdep.h
+ *
+ * @brief Common system-dependent functions
+ */
+
+#ifndef INCLUDED_SYSDEP_DOT_H
+#define INCLUDED_SYSDEP_DOT_H
+
+#include <cilk/common.h>
+#include <internal/abi.h>
+
+#include "global_state.h"
+#include "full_frame.h"
+#include "os.h"
+#include "os_mutex.h"
+
+/**
+ * @brief Default page size for Cilk stacks.
+ *
+ * All Cilk stacks should have size that is a multiple of this value.
+ */
+#define PAGE 4096
+
+/**
+ * @brief Size of a scheduling stack.
+ *
+ * A scheduling stack is used to by system workers to execute runtime
+ * code.  Since this stack is only executing runtime functions, we
+ * don't need it to be a full size stack.
+ *
+ * The number "18" should be small since the runtime doesn't require a
+ * large stack, but large enough to call "printf" for debugging.
+ */ 
+#define CILK_SCHEDULING_STACK_SIZE (18*PAGE)
+
+__CILKRTS_BEGIN_EXTERN_C
+
+
+/**
+ * Code to initialize the system-dependent portion of the global_state_t
+ *
+ * @param g Pointer to the global state.
+ */
+COMMON_SYSDEP
+void __cilkrts_init_global_sysdep(global_state_t *g);
+
+/**
+ * Code to clean up the system-dependent portion of the global_state_t
+ *
+ * @param g Pointer to the global state.
+ */
+COMMON_SYSDEP
+void __cilkrts_destroy_global_sysdep(global_state_t *g);
+
+/**
+ * Passes stack range to Cilkscreen.  This functionality should be moved
+ * into Cilkscreen.
+ */
+COMMON_SYSDEP
+void __cilkrts_establish_c_stack(void);
+
+
+/**
+ * Save system dependent information in the full_frame and
+ * __cilkrts_stack_frame.  Part of promoting a
+ * __cilkrts_stack_frame to a full_frame.
+ *
+ * @param w The worker the frame was running on.  Not used.
+ * @param ff The full frame that is being created for the
+ * __cilkrts_stack_frame.
+ * @param sf The __cilkrts_stack_frame that's being promoted
+ * to a full frame.
+ * @param state_valid ?
+ * @param why A description of why make_unrunnable was called.
+ * Used for debugging.
+ */
+COMMON_SYSDEP
+void __cilkrts_make_unrunnable_sysdep(__cilkrts_worker *w,
+                                      full_frame *ff,
+                                      __cilkrts_stack_frame *sf,
+                                      int state_valid,
+                                      const char *why);
+
+
+/**
+ * OS-specific code to spawn worker threads.
+ *
+ * @param g The global state.
+ * @param n Number of worker threads to start.
+ */
+COMMON_SYSDEP
+void __cilkrts_start_workers(global_state_t *g, int n);
+
+/**
+ * @brief OS-specific code to stop worker threads.
+ *
+ * @param g The global state.
+ */
+COMMON_SYSDEP
+void __cilkrts_stop_workers(global_state_t *g);
+
+/**
+ * @brief Imports a user thread the first time it returns to a stolen parent.
+ *
+ * The thread has been bound to a worker, but additional steps need to
+ * be taken to start running a scheduling loop.
+ *
+ * @param w The worker bound to the thread.
+ */
+COMMON_SYSDEP
+void __cilkrts_sysdep_import_user_thread(__cilkrts_worker *w);
+
+/**
+ * @brief Function to be run for each of the system worker threads.
+ * 
+ * This declaration also appears in cilk/cilk_undocumented.h -- don't
+ * change one declaration without also changing the other.
+ *
+ * @param arg The context value passed to the thread creation routine for
+ * the OS we're running on.
+ *
+ * @returns OS dependent.
+ */
+#ifdef _WIN32
+/* Do not use CILK_API because __cilkrts_worker_stub must be __stdcall */
+CILK_EXPORT unsigned __CILKRTS_NOTHROW __stdcall
+__cilkrts_worker_stub(void *arg);
+#else
+/* Do not use CILK_API because __cilkrts_worker_stub have default visibility */
+__attribute__((visibility("default")))
+void* __CILKRTS_NOTHROW __cilkrts_worker_stub(void *arg);
+#endif
+
+/**
+ * Initialize any OS-depenendent portions of a newly created
+ * __cilkrts_worker.
+ *
+ * Exported for Piersol.  Without the export, Piersol doesn't display
+ * useful information in the stack trace.  This declaration also appears in
+ * cilk/cilk_undocumented.h -- do not modify one without modifying the other.
+ *
+ * @param w The worker being initialized.
+ */
+COMMON_SYSDEP
+CILK_EXPORT
+void __cilkrts_init_worker_sysdep(__cilkrts_worker *w);
+
+/**
+ * Deallocate any OS-depenendent portions of a __cilkrts_worker.
+ *
+ * @param w The worker being deallocaed.
+ */
+COMMON_SYSDEP
+void __cilkrts_destroy_worker_sysdep(__cilkrts_worker *w);
+
+/**
+ * Called to do any OS-dependent setup before starting execution on a
+ * frame. Mostly deals with exception handling data.
+ *
+ * @param w The worker the frame will run on.
+ * @param ff The full_frame that is about to be resumed.
+ */
+COMMON_SYSDEP
+void __cilkrts_setup_for_execution_sysdep(__cilkrts_worker *w,
+                                          full_frame *ff);
+
+/**
+ * @brief OS-specific implementaton of resetting fiber and frame state
+ * to resume exeuction.
+ *
+ * This method:
+ *  1. Calculates the value of stack pointer where we should resume
+ *     execution of "sf".  This calculation uses info stored in the
+ *     fiber, and takes into account alignment and frame size.
+ *  2. Updates sf and ff to match the calculated stack pointer.
+ *
+ *  On Unix, the stack pointer calculation looks up the base of the
+ *  stack from the fiber.
+ *
+ *  On Windows, this calculation is calls "alloca" to find a stack
+ *  pointer on the currently executing stack.  Thus, the Windows code
+ *  assumes @c fiber is the currently executing fiber.
+ *
+ * @param fiber   fiber to resume execution on.
+ * @param ff      full_frame for the frame we're resuming.
+ * @param sf      __cilkrts_stack_frame that we should resume
+ * @return    The calculated stack pointer.
+ */
+COMMON_SYSDEP
+char* sysdep_reset_jump_buffers_for_resume(cilk_fiber* fiber,
+                                           full_frame *ff,
+                                           __cilkrts_stack_frame *sf);
+
+/**
+ * @brief System-dependent longjmp to user code for resuming execution
+ *   of a @c __cilkrts_stack_frame.
+ *
+ * This method:
+ *  - Changes the stack pointer in @c sf to @c new_sp.
+ *  - If @c ff_for_exceptions is not NULL, changes fields in @c sf and
+ *    @c ff_for_exceptions for exception processing.
+ *  - Restores any floating point state
+ *  - Finishes with a longjmp to user code, never to return. 
+ *
+ * @param new_sp             stack pointer where we should resume execution
+ * @param sf                 @c __cilkrts_stack_frame for the frame we're resuming.
+ * @param ff_for_exceptions  full_frame to safe exception info into, if necessary
+ */
+COMMON_SYSDEP
+NORETURN
+sysdep_longjmp_to_sf(char* new_sp,
+                     __cilkrts_stack_frame *sf,
+                     full_frame *ff_for_exceptions);
+
+/**
+ * @brief System-dependent code to save floating point control information
+ * to a @c __cilkrts_stack_frame.  This function will be called by compilers
+ * that cannot inline the code.
+ *
+ * Note that this function does *not* save the current floating point
+ * registers.  It saves the floating point control words that control
+ * precision and rounding and stuff like that.
+ *
+ * This function will be a noop for architectures that don't have warts
+ * like the floating point control words, or where the information is
+ * already being saved by the setjmp.
+ *
+ * @param sf                 @c __cilkrts_stack_frame for the frame we're
+ * saving the floating point control information in.
+ */
+COMMON_SYSDEP
+void
+sysdep_save_fp_ctrl_state(__cilkrts_stack_frame *sf);
+
+
+/**
+ * @brief restore x86 floating point state
+ *
+ * Only used for x86 and Intel64 processors
+ */
+COMMON_SYSDEP
+void restore_x86_fp_state(__cilkrts_stack_frame *sf);
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_SYSDEP_DOT_H)
diff --git a/libcilkrts/runtime/worker_mutex.c b/libcilkrts/runtime/worker_mutex.c
new file mode 100644 (file)
index 0000000..380d625
--- /dev/null
@@ -0,0 +1,121 @@
+/* worker_mutex.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+#include "worker_mutex.h"
+#include "bug.h"
+#include "os.h"
+#include "stats.h"
+
+/* m->lock == 1 means that mutex M is locked */
+#define TRY_ACQUIRE(m) (__cilkrts_xchg(&(m)->lock, 1) == 0)
+
+/* ICC 11.1+ understands release semantics and generates an
+   ordinary store with a software memory barrier. */
+#if __ICC >= 1110
+#define RELEASE(m) __sync_lock_release(&(m)->lock)
+#else
+#define RELEASE(m) __cilkrts_xchg(&(m)->lock, 0)
+#endif
+
+void __cilkrts_mutex_init(struct mutex *m)
+{
+    m->owner = 0;
+
+    // Use a simple assignment so Inspector doesn't bug us about the
+    // interlocked exchange doing a read of an uninitialized variable.
+    // By definition there can't be a race when we're initializing the
+    // lock...
+    m->lock = 0;
+}
+
+void __cilkrts_mutex_lock(__cilkrts_worker *w, struct mutex *m)
+{
+    int count;
+    const int maxspin = 1000; /* SWAG */
+
+    NOTE_INTERVAL(w, INTERVAL_MUTEX_LOCK);
+    if (!TRY_ACQUIRE(m)) {
+        START_INTERVAL(w, INTERVAL_MUTEX_LOCK_SPINNING);
+        count = 0;
+        do {
+            do {
+                __cilkrts_short_pause();
+                if (++count >= maxspin) {
+                    STOP_INTERVAL(w, INTERVAL_MUTEX_LOCK_SPINNING);
+                    START_INTERVAL(w, INTERVAL_MUTEX_LOCK_YIELDING);
+                    /* let the OS reschedule every once in a while */
+                    __cilkrts_yield();
+                    STOP_INTERVAL(w, INTERVAL_MUTEX_LOCK_YIELDING);
+                    START_INTERVAL(w, INTERVAL_MUTEX_LOCK_SPINNING);
+                    count = 0;
+                }
+            } while (m->lock != 0);
+        } while (!TRY_ACQUIRE(m));
+        STOP_INTERVAL(w, INTERVAL_MUTEX_LOCK_SPINNING);
+    }
+
+    CILK_ASSERT(m->owner == 0);
+    m->owner = w;
+}
+
+int __cilkrts_mutex_trylock(__cilkrts_worker *w, struct mutex *m)
+{
+    NOTE_INTERVAL(w, INTERVAL_MUTEX_TRYLOCK);
+    if (TRY_ACQUIRE(m)) {
+        CILK_ASSERT(m->owner == 0);
+        m->owner = w;
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+void __cilkrts_mutex_unlock(__cilkrts_worker *w, struct mutex *m)
+{
+    CILK_ASSERT(m->owner == w);
+    m->owner = 0;
+    RELEASE(m);
+}
+
+void __cilkrts_mutex_destroy(__cilkrts_worker *w, struct mutex *m)
+{
+    (void)w; /* unused */
+    (void)m; /* unused */
+}
+
+/* End worker_mutex.c */
diff --git a/libcilkrts/runtime/worker_mutex.h b/libcilkrts/runtime/worker_mutex.h
new file mode 100644 (file)
index 0000000..c2c6824
--- /dev/null
@@ -0,0 +1,131 @@
+/* worker_mutex.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ **************************************************************************/
+
+/**
+ * @file worker_mutex.h
+ *
+ * @brief Support for Cilk runtime mutexes.
+ *
+ * Cilk runtime mutexes are implemented as simple spin loops.
+ */
+
+#ifndef INCLUDED_WORKER_MUTEX_DOT_H
+#define INCLUDED_WORKER_MUTEX_DOT_H
+
+#include <cilk/common.h>
+#include "rts-common.h"
+
+__CILKRTS_BEGIN_EXTERN_C
+
+/**
+ * Mutexes are treated as an abstract data type within the Cilk
+ * runtime system.  They are implemented as simple spin loops and
+ * owned by a __cilkrts_worker.
+ */
+typedef struct mutex {
+    /** Mutex spin loop variable. 0 if unowned, 1 if owned. */
+    volatile int lock;
+
+    /** Worker that owns the mutex.  Must be 0 if mutex is unowned. */
+    __cilkrts_worker *owner;
+} mutex;
+
+/**
+ * @brief Initialize a Cilk mutex.
+ *
+ * @param m Mutex to be initialized.
+ */
+COMMON_PORTABLE
+void __cilkrts_mutex_init(struct mutex *m);
+
+/**
+ * @brief Acquire a Cilk mutex.
+ *
+ * If statistics are being gathered, the time spent
+ * acquiring the mutex will be attributed to the specified worker.
+ *
+ * @param w Worker that will become the owner of this mutex.
+ * @param m Mutex to be initialized.
+ */
+COMMON_PORTABLE
+void __cilkrts_mutex_lock(__cilkrts_worker *w,
+                          struct mutex *m);
+/**
+ * @brief Attempt to lock a Cilk mutex and fail if it isn't available.
+ *
+ * If statistics are being gathered, the time spent acquiring the
+ * mutex will be attributed to the specified worker.
+ *
+ * @param w Worker that will become the owner of this mutex.
+ * @param m Mutex to be acquired.
+ *
+ * @return 1 if the mutex was acquired.
+ * @return 0 if the mutex was not acquired.
+ */
+COMMON_PORTABLE
+int __cilkrts_mutex_trylock(__cilkrts_worker *w,
+                            struct mutex *m);
+
+/**
+ * @brief Release a Cilk mutex.
+ * 
+ * If statistics are being gathered, the time spent
+ * acquiring the mutex will be attributed to the specified worker.
+ *
+ * @pre The mutex must be owned by the worker.
+ *
+ * @param w Worker that owns this mutex.
+ * @param m Mutex to be released.
+ */
+COMMON_PORTABLE
+void __cilkrts_mutex_unlock(__cilkrts_worker *w,
+                            struct mutex *m);
+
+/**
+ * @brief Deallocate a Cilk mutex.  Currently does nothing.
+ *
+ * @param w Unused.
+ * @param m Mutex to be deallocated.
+ */
+COMMON_PORTABLE
+void __cilkrts_mutex_destroy(__cilkrts_worker *w,
+                             struct mutex *m);
+
+__CILKRTS_END_EXTERN_C
+
+#endif // ! defined(INCLUDED_WORKER_MUTEX_DOT_H)