This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[trans-mem] initial commit of runtime library


I'm about 75% of the way to having something that should run simple test cases on x86 linux. But it's been 10+ days since I've committed anything and that seems a bit too long to have it all sitting only on my laptop.


r~
--- Makefile.def	(revision 141843)
+++ Makefile.def	(local)
@@ -154,6 +154,7 @@ target_modules = { module= qthreads; };
 target_modules = { module= rda; };
 target_modules = { module= libada; };
 target_modules = { module= libgomp; lib_path=.libs; };
+target_modules = { module= libitm; lib_path=.libs; };
 
 // These are (some of) the make targets to be done in each subdirectory.
 // Not all; these are the ones which don't have special options.
--- configure.ac	(revision 141843)
+++ configure.ac	(local)
@@ -182,6 +182,7 @@ target_libraries="target-libgcc \
 		target-libgloss \
 		target-newlib \
 		target-libgomp \
+		target-libitm \
 		target-libstdc++-v3 \
 		target-libmudflap \
 		target-libssp \
@@ -439,6 +440,24 @@ if test x$enable_libgomp = x ; then
     esac
 fi
 
+# Disable libitm on non POSIX hosted systems.
+if test x$enable_libitm = x ; then
+    # Enable libitm by default on hosted POSIX systems.
+    case "${target}" in
+    *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu)
+	;;
+    *-*-netbsd* | *-*-freebsd* | *-*-openbsd*)
+	;;
+    *-*-solaris2* | *-*-sysv4* | *-*-irix6* | *-*-osf* | *-*-hpux11*)
+	;;
+    *-*-darwin* | *-*-aix*)
+	;;
+    *)
+	noconfigdirs="$noconfigdirs target-libitm"
+	;;
+    esac
+fi
+
 # Default libgloss CPU subdirectory.
 libgloss_dir="$target_cpu"
 
=== libitm	(new directory)
==================================================================
--- libitm/Makefile.am	(revision 141843)
+++ libitm/Makefile.am	(local)
@@ -0,0 +1,37 @@
+## Process this file with automake to produce Makefile.in
+
+ACLOCAL_AMFLAGS = -I .. -I ../config
+SUBDIRS = testsuite
+
+## May be used by toolexeclibdir.
+gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
+
+config_path = @config_path@
+search_path = $(addprefix $(top_srcdir)/config/, $(config_path)) $(top_srcdir)
+
+fincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/finclude
+libsubincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
+
+vpath % $(strip $(search_path))
+
+AM_CPPFLAGS = $(addprefix -I, $(search_path))
+AM_CFLAGS = $(XCFLAGS)
+AM_LDFLAGS = $(XLDFLAGS) $(SECTION_LDFLAGS) $(OPT_LDFLAGS)
+
+CCAS = $(CC)
+CCASFLAGS = $(CFLAGS)
+
+toolexeclib_LTLIBRARIES = libitm.la
+nodist_toolexeclib_HEADERS = libitm.spec
+
+if LIBITM_BUILD_VERSIONED_SHLIB
+libitm_version_script = -Wl,--version-script,$(top_srcdir)/libitm.map
+else
+libitm_version_script =
+endif
+libitm_version_info = -version-info $(libtool_VERSION)
+libitm_la_LDFLAGS = $(libitm_version_info) $(libitm_version_script) \
+        -no-undefined
+
+libitm_la_SOURCES = beginend.c dispatch.c local.c query.c retry.c \
+	rwlock.c serial.c sjlj.S useraction.c futex.c
--- libitm/acinclude.m4	(revision 141843)
+++ libitm/acinclude.m4	(local)
@@ -0,0 +1,303 @@
+dnl ----------------------------------------------------------------------
+dnl This whole bit snagged from libgfortran.
+
+dnl Check whether the target supports __sync_*_compare_and_swap.
+AC_DEFUN([LIBITM_CHECK_SYNC_BUILTINS], [
+  AC_CACHE_CHECK([whether the target supports __sync_*_compare_and_swap],
+		 libitm_cv_have_sync_builtins, [
+  AC_TRY_LINK([], [int foo, bar; bar = __sync_val_compare_and_swap(&foo, 0, 1);],
+	      libitm_cv_have_sync_builtins=yes, libitm_cv_have_sync_builtins=no)])
+  if test $libitm_cv_have_sync_builtins = yes; then
+    AC_DEFINE(HAVE_SYNC_BUILTINS, 1,
+	      [Define to 1 if the target supports __sync_*_compare_and_swap])
+  fi])
+
+dnl Check whether the target supports hidden visibility.
+AC_DEFUN([LIBITM_CHECK_ATTRIBUTE_VISIBILITY], [
+  AC_CACHE_CHECK([whether the target supports hidden visibility],
+		 libitm_cv_have_attribute_visibility, [
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  AC_TRY_COMPILE([void __attribute__((visibility("hidden"))) foo(void) { }],
+		 [], libitm_cv_have_attribute_visibility=yes,
+		 libitm_cv_have_attribute_visibility=no)
+  CFLAGS="$save_CFLAGS"])
+  if test $libitm_cv_have_attribute_visibility = yes; then
+    AC_DEFINE(HAVE_ATTRIBUTE_VISIBILITY, 1,
+      [Define to 1 if the target supports __attribute__((visibility(...))).])
+  fi])
+
+dnl Check whether the target supports dllexport
+AC_DEFUN([LIBITM_CHECK_ATTRIBUTE_DLLEXPORT], [
+  AC_CACHE_CHECK([whether the target supports dllexport],
+		 libitm_cv_have_attribute_dllexport, [
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  AC_TRY_COMPILE([void __attribute__((dllexport)) foo(void) { }],
+		 [], libitm_cv_have_attribute_dllexport=yes,
+		 libitm_cv_have_attribute_dllexport=no)
+  CFLAGS="$save_CFLAGS"])
+  if test $libitm_cv_have_attribute_dllexport = yes; then
+    AC_DEFINE(HAVE_ATTRIBUTE_DLLEXPORT, 1,
+      [Define to 1 if the target supports __attribute__((dllexport)).])
+  fi])
+
+dnl Check whether the target supports symbol aliases.
+AC_DEFUN([LIBITM_CHECK_ATTRIBUTE_ALIAS], [
+  AC_CACHE_CHECK([whether the target supports symbol aliases],
+		 libitm_cv_have_attribute_alias, [
+  AC_TRY_LINK([
+void foo(void) { }
+extern void bar(void) __attribute__((alias("foo")));],
+    [bar();], libitm_cv_have_attribute_alias=yes, libitm_cv_have_attribute_alias=no)])
+  if test $libitm_cv_have_attribute_alias = yes; then
+    AC_DEFINE(HAVE_ATTRIBUTE_ALIAS, 1,
+      [Define to 1 if the target supports __attribute__((alias(...))).])
+  fi])
+
+sinclude(../libtool.m4)
+dnl The lines below arrange for aclocal not to bring an installed
+dnl libtool.m4 into aclocal.m4, while still arranging for automake to
+dnl add a definition of LIBTOOL to Makefile.in.
+ifelse(,,,[AC_SUBST(LIBTOOL)
+AC_DEFUN([AM_PROG_LIBTOOL])
+AC_DEFUN([AC_LIBTOOL_DLOPEN])
+AC_DEFUN([AC_PROG_LD])
+])
+
+dnl ----------------------------------------------------------------------
+dnl This whole bit snagged from libstdc++-v3.
+
+dnl
+dnl LIBITM_ENABLE
+dnl    (FEATURE, DEFAULT, HELP-ARG, HELP-STRING)
+dnl    (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, permit a|b|c)
+dnl    (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, SHELL-CODE-HANDLER)
+dnl
+dnl See docs/html/17_intro/configury.html#enable for documentation.
+dnl
+m4_define([LIBITM_ENABLE],[dnl
+m4_define([_g_switch],[--enable-$1])dnl
+m4_define([_g_help],[AC_HELP_STRING(_g_switch$3,[$4 @<:@default=$2@:>@])])dnl
+ AC_ARG_ENABLE($1,_g_help,
+  m4_bmatch([$5],
+   [^permit ],
+     [[
+      case "$enableval" in
+       m4_bpatsubst([$5],[permit ])) ;;
+       *) AC_MSG_ERROR(Unknown argument to enable/disable $1) ;;
+          dnl Idea for future:  generate a URL pointing to
+          dnl "onlinedocs/configopts.html#whatever"
+      esac
+     ]],
+   [^$],
+     [[
+      case "$enableval" in
+       yes|no) ;;
+       *) AC_MSG_ERROR(Argument to enable/disable $1 must be yes or no) ;;
+      esac
+     ]],
+   [[$5]]),
+  [enable_]m4_bpatsubst([$1],-,_)[=][$2])
+m4_undefine([_g_switch])dnl
+m4_undefine([_g_help])dnl
+])
+
+
+dnl
+dnl If GNU ld is in use, check to see if tricky linker opts can be used.  If
+dnl the native linker is in use, all variables will be defined to something
+dnl safe (like an empty string).
+dnl
+dnl Defines:
+dnl  SECTION_LDFLAGS='-Wl,--gc-sections' if possible
+dnl  OPT_LDFLAGS='-Wl,-O1' if possible
+dnl  LD (as a side effect of testing)
+dnl Sets:
+dnl  with_gnu_ld
+dnl  libitm_gnu_ld_version (possibly)
+dnl
+dnl The last will be a single integer, e.g., version 1.23.45.0.67.89 will
+dnl set libitm_gnu_ld_version to 12345.  Zeros cause problems.
+dnl
+AC_DEFUN([LIBITM_CHECK_LINKER_FEATURES], [
+  # If we're not using GNU ld, then there's no point in even trying these
+  # tests.  Check for that first.  We should have already tested for gld
+  # by now (in libtool), but require it now just to be safe...
+  test -z "$SECTION_LDFLAGS" && SECTION_LDFLAGS=''
+  test -z "$OPT_LDFLAGS" && OPT_LDFLAGS=''
+  AC_REQUIRE([AC_PROG_LD])
+  AC_REQUIRE([AC_PROG_AWK])
+
+  # The name set by libtool depends on the version of libtool.  Shame on us
+  # for depending on an impl detail, but c'est la vie.  Older versions used
+  # ac_cv_prog_gnu_ld, but now it's lt_cv_prog_gnu_ld, and is copied back on
+  # top of with_gnu_ld (which is also set by --with-gnu-ld, so that actually
+  # makes sense).  We'll test with_gnu_ld everywhere else, so if that isn't
+  # set (hence we're using an older libtool), then set it.
+  if test x${with_gnu_ld+set} != xset; then
+    if test x${ac_cv_prog_gnu_ld+set} != xset; then
+      # We got through "ac_require(ac_prog_ld)" and still not set?  Huh?
+      with_gnu_ld=no
+    else
+      with_gnu_ld=$ac_cv_prog_gnu_ld
+    fi
+  fi
+
+  # Start by getting the version number.  I think the libtool test already
+  # does some of this, but throws away the result.
+  changequote(,)
+  ldver=`$LD --version 2>/dev/null | head -1 | \
+         sed -e 's/GNU ld \(version \)\{0,1\}\(([^)]*) \)\{0,1\}\([0-9.][0-9.]*\).*/\3/'`
+  changequote([,])
+  libitm_gnu_ld_version=`echo $ldver | \
+         $AWK -F. '{ if (NF<3) [$]3=0; print ([$]1*100+[$]2)*100+[$]3 }'`
+
+  # Set --gc-sections.
+  if test "$with_gnu_ld" = "notbroken"; then
+    # GNU ld it is!  Joy and bunny rabbits!
+
+    # All these tests are for C++; save the language and the compiler flags.
+    # Need to do this so that g++ won't try to link in libstdc++
+    ac_test_CFLAGS="${CFLAGS+set}"
+    ac_save_CFLAGS="$CFLAGS"
+    CFLAGS='-x c++  -Wl,--gc-sections'
+
+    # Check for -Wl,--gc-sections
+    # XXX This test is broken at the moment, as symbols required for linking
+    # are now in libsupc++ (not built yet).  In addition, this test has
+    # cored on solaris in the past.  In addition, --gc-sections doesn't
+    # really work at the moment (keeps on discarding used sections, first
+    # .eh_frame and now some of the glibc sections for iconv).
+    # Bzzzzt.  Thanks for playing, maybe next time.
+    AC_MSG_CHECKING([for ld that supports -Wl,--gc-sections])
+    AC_TRY_RUN([
+     int main(void)
+     {
+       try { throw 1; }
+       catch (...) { };
+       return 0;
+     }
+    ], [ac_sectionLDflags=yes],[ac_sectionLDflags=no], [ac_sectionLDflags=yes])
+    if test "$ac_test_CFLAGS" = set; then
+      CFLAGS="$ac_save_CFLAGS"
+    else
+      # this is the suspicious part
+      CFLAGS=''
+    fi
+    if test "$ac_sectionLDflags" = "yes"; then
+      SECTION_LDFLAGS="-Wl,--gc-sections $SECTION_LDFLAGS"
+    fi
+    AC_MSG_RESULT($ac_sectionLDflags)
+  fi
+
+  # Set linker optimization flags.
+  if test x"$with_gnu_ld" = x"yes"; then
+    OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"
+  fi
+
+  AC_SUBST(SECTION_LDFLAGS)
+  AC_SUBST(OPT_LDFLAGS)
+])
+
+
+dnl
+dnl Add version tags to symbols in shared library (or not), additionally
+dnl marking other symbols as private/local (or not).
+dnl
+dnl --enable-symvers=style adds a version script to the linker call when
+dnl       creating the shared library.  The choice of version script is
+dnl       controlled by 'style'.
+dnl --disable-symvers does not.
+dnl  +  Usage:  LIBITM_ENABLE_SYMVERS[(DEFAULT)]
+dnl       Where DEFAULT is either 'yes' or 'no'.  Passing `yes' tries to
+dnl       choose a default style based on linker characteristics.  Passing
+dnl       'no' disables versioning.
+dnl
+AC_DEFUN([LIBITM_ENABLE_SYMVERS], [
+
+LIBITM_ENABLE(symvers,yes,[=STYLE],
+  [enables symbol versioning of the shared library],
+  [permit yes|no|gnu])
+
+# If we never went through the LIBITM_CHECK_LINKER_FEATURES macro, then we
+# don't know enough about $LD to do tricks...
+AC_REQUIRE([LIBITM_CHECK_LINKER_FEATURES])
+# FIXME  The following test is too strict, in theory.
+if test $enable_shared = no ||
+        test "x$LD" = x ||
+        test x$libitm_gnu_ld_version = x; then
+  enable_symvers=no
+fi
+
+# Check to see if libgcc_s exists, indicating that shared libgcc is possible.
+if test $enable_symvers != no; then
+  AC_MSG_CHECKING([for shared libgcc])
+  ac_save_CFLAGS="$CFLAGS"
+  CFLAGS=' -lgcc_s'
+  AC_TRY_LINK(, [return 0;], libitm_shared_libgcc=yes, libitm_shared_libgcc=no)
+  CFLAGS="$ac_save_CFLAGS"
+  if test $libitm_shared_libgcc = no; then
+    cat > conftest.c <<EOF
+int main (void) { return 0; }
+EOF
+changequote(,)dnl
+    libitm_libgcc_s_suffix=`${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
+			     -shared -shared-libgcc -o conftest.so \
+			     conftest.c -v 2>&1 >/dev/null \
+			     | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'`
+changequote([,])dnl
+    rm -f conftest.c conftest.so
+    if test x${libitm_libgcc_s_suffix+set} = xset; then
+      CFLAGS=" -lgcc_s$libitm_libgcc_s_suffix"
+      AC_TRY_LINK(, [return 0;], libitm_shared_libgcc=yes)
+      CFLAGS="$ac_save_CFLAGS"
+    fi
+  fi
+  AC_MSG_RESULT($libitm_shared_libgcc)
+fi
+
+# For GNU ld, we need at least this version.  The format is described in
+# LIBITM_CHECK_LINKER_FEATURES above.
+libitm_min_gnu_ld_version=21400
+# XXXXXXXXXXX libitm_gnu_ld_version=21390
+
+# Check to see if unspecified "yes" value can win, given results above.
+# Change "yes" into either "no" or a style name.
+if test $enable_symvers = yes; then
+  if test $with_gnu_ld = yes &&
+     test $libitm_shared_libgcc = yes;
+  then
+    if test $libitm_gnu_ld_version -ge $libitm_min_gnu_ld_version ; then
+      enable_symvers=gnu
+    else
+      # The right tools, the right setup, but too old.  Fallbacks?
+      AC_MSG_WARN(=== Linker version $libitm_gnu_ld_version is too old for)
+      AC_MSG_WARN(=== full symbol versioning support in this release of GCC.)
+      AC_MSG_WARN(=== You would need to upgrade your binutils to version)
+      AC_MSG_WARN(=== $libitm_min_gnu_ld_version or later and rebuild GCC.)
+      if test $libitm_gnu_ld_version -ge 21200 ; then
+        # Globbing fix is present, proper block support is not.
+        dnl AC_MSG_WARN([=== Dude, you are soooo close.  Maybe we can fake it.])
+        dnl enable_symvers=???
+        AC_MSG_WARN([=== Symbol versioning will be disabled.])
+        enable_symvers=no
+      else
+        # 2.11 or older.
+        AC_MSG_WARN([=== Symbol versioning will be disabled.])
+        enable_symvers=no
+      fi
+    fi
+  else
+    # just fail for now
+    AC_MSG_WARN([=== You have requested some kind of symbol versioning, but])
+    AC_MSG_WARN([=== either you are not using a supported linker, or you are])
+    AC_MSG_WARN([=== not building a shared libgcc_s (which is required).])
+    AC_MSG_WARN([=== Symbol versioning will be disabled.])
+    enable_symvers=no
+  fi
+fi
+
+AM_CONDITIONAL(LIBITM_BUILD_VERSIONED_SHLIB, test $enable_symvers != no)
+AC_MSG_NOTICE(versioning on shared library symbols is $enable_symvers)
+])
--- libitm/beginend.c	(revision 141843)
+++ libitm/beginend.c	(local)
@@ -0,0 +1,192 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#include "libitm.h"
+
+
+__thread struct gtm_thread gtm_thr;
+gtm_rwlock gtm_serial_lock;
+
+/* ??? Move elsewhere when we figure out library initialization.  */
+unsigned long long gtm_spin_count_var = 1000;
+
+static uint32_t global_tid;
+
+/* Allocate a transaction structure.  Reuse an old one if possible.  */
+
+static struct gtm_transaction *
+alloc_tx (void)
+{
+  struct gtm_transaction *tx;
+
+  if (gtm_thr.free_tx_count == 0)
+    tx = malloc (sizeof (*tx));
+  else
+    {
+      gtm_thr.free_tx_count--;
+      tx = gtm_thr.free_tx[gtm_thr.free_tx_idx];
+      gtm_thr.free_tx_idx = (gtm_thr.free_tx_idx + 1) % MAX_FREE_TX;
+    }
+
+  return tx;
+}
+
+/* Queue a transaction structure for freeing.  We never free the given
+   transaction immediately -- this is a requirement of abortTransaction
+   as the jmpbuf is used immediately after calling this function.  Thus
+   the requirement that this queue be per-thread.  */
+
+static void
+free_tx (struct gtm_transaction *tx)
+{
+  unsigned idx = (gtm_thr.free_tx_idx + gtm_thr.free_tx_count) % MAX_FREE_TX;
+
+  if (gtm_thr.free_tx_count == MAX_FREE_TX)
+    {
+      gtm_thr.free_tx_idx = (gtm_thr.free_tx_idx + 1) % MAX_FREE_TX;
+      free (gtm_thr.free_tx[idx]);
+    }
+  else
+    gtm_thr.free_tx_count++;
+
+  gtm_thr.free_tx[idx] = tx;
+}
+
+
+uint32_t REGPARM
+GTM_begin_transaction (uint32_t prop, const struct gtm_jmpbuf *jb)
+{
+  struct gtm_transaction *tx = alloc_tx ();
+
+  memset (tx, 0, sizeof (*tx));
+
+  tx->prop = prop;
+  tx->prev = gtm_thr.tx;
+  if (tx->prev)
+    tx->nesting = tx->prev->nesting + 1;
+  tx->id = __sync_add_and_fetch (&global_tid, 1);
+  tx->jb = *jb;
+
+  gtm_thr.tx = tx;
+
+  if ((prop & pr_doesGoIrrevocable) || !(prop & pr_instrumentedCode))
+    {
+      GTM_serialmode (true);
+      return (prop & pr_uninstrumentedCode
+	      ? a_runUninstrumentedCode : a_runInstrumentedCode);
+    }
+
+  gtm_rwlock_read_lock (&gtm_serial_lock);
+
+  return a_runInstrumentedCode | a_saveLiveVariables;
+}
+
+static void
+GTM_rollback_transaction (void)
+{
+  gtm_thr.disp->rollback ();
+  GTM_rollback_local ();
+  GTM_free_actions (&gtm_thr.tx->commit_actions);
+  GTM_run_actions (&gtm_thr.tx->undo_actions);
+}
+
+void REGPARM
+_ITM_rollbackTransaction (const _ITM_srcLocation * loc UNUSED)
+{
+  assert ((gtm_thr.tx->prop & pr_hasNoAbort) == 0);
+  assert ((gtm_thr.tx->state & STATE_ABORTING) == 0);
+
+  GTM_rollback_transaction ();
+  gtm_thr.tx->state |= STATE_ABORTING;
+}
+
+void REGPARM
+_ITM_abortTransaction (_ITM_abortReason reason,
+		       const _ITM_srcLocation *loc UNUSED)
+{
+  struct gtm_transaction *tx;
+
+  assert (reason == userAbort);
+  assert ((gtm_thr.tx->prop & pr_hasNoAbort) == 0);
+  assert ((gtm_thr.tx->state & STATE_ABORTING) == 0);
+
+  GTM_rollback_transaction ();
+
+  if (gtm_thr.tx->state & STATE_SERIAL)
+    gtm_rwlock_write_unlock (&gtm_serial_lock);
+  else
+    gtm_rwlock_read_unlock (&gtm_serial_lock);
+
+  tx = gtm_thr.tx;
+  gtm_thr.tx = tx->prev;
+  free_tx (tx);
+
+  GTM_longjmp (&tx->jb, a_abortTransaction | a_restoreLiveVariables);
+}
+
+static bool
+GTM_trycommit_transaction (void)
+{
+  if (gtm_thr.disp->trycommit ())
+    {
+      GTM_commit_local ();
+      GTM_free_actions (&gtm_thr.tx->undo_actions);
+      GTM_run_actions (&gtm_thr.tx->commit_actions);
+      return true;
+    }
+  return false;
+}
+
+bool REGPARM
+_ITM_tryCommitTransaction (const _ITM_srcLocation *loc UNUSED)
+{
+  assert ((gtm_thr.tx->state & STATE_ABORTING) == 0);
+  return GTM_trycommit_transaction ();
+}
+
+void REGPARM
+_ITM_commitTransaction(const _ITM_srcLocation *loc UNUSED)
+{
+  struct gtm_transaction *tx = gtm_thr.tx;
+  uint32_t actions;
+
+  if ((tx->state & STATE_ABORTING) || GTM_trycommit_transaction ())
+    {
+      gtm_thr.tx = tx->prev;
+      free_tx (tx);
+      return;
+    }
+
+  GTM_decide_retry_strategy ();
+
+  actions = a_runInstrumentedCode | a_restoreLiveVariables;
+  if ((tx->prop & (pr_doesGoIrrevocable | pr_uninstrumentedCode))
+      == (pr_doesGoIrrevocable | pr_uninstrumentedCode))
+    actions = a_runUninstrumentedCode | a_restoreLiveVariables;
+
+  GTM_longjmp (&tx->jb, actions);
+}
=== libitm/config	(new directory)
==================================================================
=== libitm/config/linux	(new directory)
==================================================================
--- libitm/config/linux/futex.c	(revision 141843)
+++ libitm/config/linux/futex.c	(local)
@@ -0,0 +1,76 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+/* Provide access to the futex system call.  */
+
+#include "libitm.h"
+#include "futex.h"
+#include <errno.h>
+
+
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG	128L
+
+
+static long int gtm_futex_wait = FUTEX_WAIT | FUTEX_PRIVATE_FLAG;
+static long int gtm_futex_wake = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
+
+
+void REGPARM
+futex_wait (int *addr, int val)
+{
+  unsigned long long i, count = gtm_spin_count_var;
+  long res;
+
+  for (i = 0; i < count; i++)
+    if (__builtin_expect (*addr != val, 0))
+      return;
+    else
+      cpu_relax ();
+
+  res = sys_futex0 (addr, gtm_futex_wait, val);
+  if (__builtin_expect (res == -ENOSYS, 0))
+    {
+      gtm_futex_wait = FUTEX_WAIT;
+      gtm_futex_wake = FUTEX_WAKE;
+      sys_futex0 (addr, FUTEX_WAIT, val);
+    }
+}
+
+
+void REGPARM
+futex_wake (int *addr, int count)
+{
+  long res = sys_futex0 (addr, gtm_futex_wake, count);
+  if (__builtin_expect (res == -ENOSYS, 0))
+    {
+      gtm_futex_wait = FUTEX_WAIT;
+      gtm_futex_wake = FUTEX_WAKE;
+      sys_futex0 (addr, FUTEX_WAKE, count);
+    }
+}
--- libitm/config/linux/futex.h	(revision 141843)
+++ libitm/config/linux/futex.h	(local)
@@ -0,0 +1,46 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+/* Provide access to the futex system call.  */
+
+#ifndef GTM_FUTEX_H
+#define GTM_FUTEX_H 1
+
+#ifdef HAVE_ATTRIBUTE_VISIBILITY
+# pragma GCC visibility push(hidden)
+#endif
+
+#include "futex_bits.h"
+
+extern void futex_wait (int *addr, int val) REGPARM;
+extern void futex_wake (int *addr, int count) REGPARM;
+
+#ifdef HAVE_ATTRIBUTE_VISIBILITY
+# pragma GCC visibility pop
+#endif
+
+#endif /* GTM_FUTEX_H */
--- libitm/config/linux/rwlock.c	(revision 141843)
+++ libitm/config/linux/rwlock.c	(local)
@@ -0,0 +1,257 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#include <limits.h>
+#include "libitm.h"
+#include "futex.h"
+
+
+/* Lock the summary bit on LOCK.  Return the contents of the summary word
+   (without the summary lock bit included).  */
+
+static int REGPARM
+rwlock_lock_summary (gtm_rwlock *lock)
+{
+  int o;
+
+ restart:
+  o = __sync_fetch_and_or (&lock->summary, RWLOCK_S_LOCK);
+  if (o & RWLOCK_S_LOCK)
+    {
+      do
+	cpu_relax ();
+      while (lock->summary & RWLOCK_S_LOCK);
+      goto restart;
+    }
+
+  return o;
+}
+
+
+/* Acquire a RW lock for reading.  */
+
+void REGPARM
+gtm_rwlock_read_lock (gtm_rwlock *lock)
+{
+  int o, n;
+
+  while (1)
+    {
+      o = rwlock_lock_summary (lock);
+
+      /* If there is an active or waiting writer, then new readers
+	 must wait.  Increment the waiting reader count, then wait
+	 on the reader queue.  */
+      if (o & (RWLOCK_A_WRITER | RWLOCK_W_WRITER | RWLOCK_RW_UPGRADE))
+	{
+	  n = ++lock->w_readers;
+	  atomic_write_barrier ();
+	  lock->summary = o | RWLOCK_W_READER;
+	  futex_wait (&lock->w_readers, n);
+	  continue;
+	}
+
+      /* Otherwise, we may become a reader.  */
+      ++lock->a_readers;
+      atomic_write_barrier ();
+      lock->summary = o | RWLOCK_A_READER;
+      return;
+    }
+}
+
+
+/* Acquire a RW lock for writing.  */
+
+void REGPARM
+gtm_rwlock_write_lock (gtm_rwlock *lock)
+{
+  int o, n;
+
+ restart:
+  o = lock->summary;
+
+  /* If anyone is manipulating the summary lock, the rest of the
+     data structure is volatile.  */
+  if (o & RWLOCK_S_LOCK)
+    {
+      cpu_relax ();
+      goto restart;
+    }
+
+  /* If there is an active reader or active writer, then new writers
+     must wait.  Increment the waiting writer count, then wait
+     on the writer queue.  */
+  if (o & (RWLOCK_A_WRITER | RWLOCK_A_READER | RWLOCK_RW_UPGRADE))
+    {
+      /* Grab the summary lock.  We'll need it for incrementing
+	 the waiting reader.  */
+      n = o | RWLOCK_S_LOCK;
+      if (!__sync_bool_compare_and_swap (&lock->summary, o, n))
+	goto restart;
+
+      n = ++lock->w_writers;
+      atomic_write_barrier ();
+      lock->summary = o | RWLOCK_W_WRITER;
+      futex_wait (&lock->w_writers, n);
+      goto restart;
+    }
+
+  /* Otherwise, may become a writer.  */
+  n = o | RWLOCK_A_WRITER;
+  if (!__sync_bool_compare_and_swap (&lock->summary, o, n))
+    goto restart;
+}
+
+
+/* Upgrade a RW lock that has been locked for reading to a writing lock.
+   Do this without possibility of another writer incoming.  Return false
+   if this attempt fails.  */
+
+bool REGPARM
+gtm_rwlock_write_upgrade (gtm_rwlock *lock)
+{
+  int o, n;
+
+ restart:
+  o = lock->summary;
+
+  /* If anyone is manipulating the summary lock, the rest of the
+     data structure is volatile.  */
+  if (o & RWLOCK_S_LOCK)
+    {
+      cpu_relax ();
+      goto restart;
+    }
+
+  /* If there's already someone trying to upgrade, then we fail.  */
+  if (o & RWLOCK_RW_UPGRADE)
+    return false;
+
+  /* Grab the summary lock.  We'll need it for manipulating the
+     active reader count or the waiting writer count.  */
+  n = o | RWLOCK_S_LOCK;
+  if (!__sync_bool_compare_and_swap (&lock->summary, o, n))
+    goto restart;
+
+  /* If there are more active readers, then we have to wait.  */
+  if (--lock->a_readers > 0)
+    {
+      atomic_write_barrier ();
+      o |= RWLOCK_RW_UPGRADE;
+      lock->summary = o;
+      do
+	{
+	  futex_wait (&lock->summary, o);
+	  o = lock->summary;
+	}
+      while (o & RWLOCK_A_READER);
+    }
+
+  atomic_write_barrier ();
+  o &= ~(RWLOCK_A_READER | RWLOCK_RW_UPGRADE);
+  o |= RWLOCK_A_WRITER;
+  lock->summary = o;
+  return true;
+}
+
+
+/* Release a RW lock from reading.  */
+
+void REGPARM
+gtm_rwlock_read_unlock (gtm_rwlock *lock)
+{
+  int o;
+
+  o = rwlock_lock_summary (lock);
+
+  /* If there are still active readers, nothing else to do.  */
+  if (--lock->a_readers > 0)
+    {
+      atomic_write_barrier ();
+      lock->summary = o;
+      return;
+    }
+  o &= ~RWLOCK_A_READER;
+
+  /* If there is a waiting upgrade, wake it.  */
+  if (o & RWLOCK_RW_UPGRADE)
+    {
+      atomic_write_barrier ();
+      lock->summary = o;
+      futex_wake (&lock->summary, 1);
+      return;
+    }
+
+  /* If there is a waiting writer, wake it.  */
+  if (o & RWLOCK_W_WRITER)
+    {
+      if (--lock->w_writers == 0)
+	o &= ~RWLOCK_W_WRITER;
+      atomic_write_barrier ();
+      lock->summary = o;
+      futex_wake (&lock->w_writers, 1);
+      return;
+    }
+
+  atomic_write_barrier ();
+  lock->summary = o;
+}
+
+
+/* Release a RW lock from writing.  */
+
+void REGPARM
+gtm_rwlock_write_unlock (gtm_rwlock *lock)
+{
+  int o;
+
+  o = rwlock_lock_summary (lock);
+  o &= ~RWLOCK_A_WRITER;
+
+  /* If there is a waiting writer, wake it.  */
+  if (o & RWLOCK_W_WRITER)
+    {
+      if (--lock->w_writers == 0)
+	o &= ~RWLOCK_W_WRITER;
+      atomic_write_barrier ();
+      lock->summary = o;
+      futex_wake (&lock->w_writers, 1);
+      return;
+    }
+
+  /* If there are waiting readers, wake them.  */
+  if (o & RWLOCK_W_READER)
+    {
+      lock->w_readers = 0;
+      atomic_write_barrier ();
+      lock->summary = o & ~RWLOCK_W_READER;
+      futex_wake (&lock->w_readers, INT_MAX);
+      return;
+    }
+
+  lock->summary = o;
+}
--- libitm/config/linux/rwlock.h	(revision 141843)
+++ libitm/config/linux/rwlock.h	(local)
@@ -0,0 +1,53 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#ifndef GTM_RWLOCK_H
+#define GTM_RWLOCK_H
+
+/* The read-write summary definition.  */
+
+#define RWLOCK_S_LOCK		1
+#define RWLOCK_A_WRITER		2
+#define RWLOCK_W_WRITER		4
+#define RWLOCK_A_READER		8
+#define RWLOCK_W_READER		16
+#define RWLOCK_RW_UPGRADE	32
+
+typedef struct {
+  int summary;
+  int a_readers;
+  int w_readers;
+  int w_writers;
+} gtm_rwlock;
+
+extern void REGPARM gtm_rwlock_read_lock (gtm_rwlock *);
+extern void REGPARM gtm_rwlock_write_lock (gtm_rwlock *);
+extern bool REGPARM gtm_rwlock_write_upgrade (gtm_rwlock *);
+extern void REGPARM gtm_rwlock_read_unlock (gtm_rwlock *);
+extern void REGPARM gtm_rwlock_write_unlock (gtm_rwlock *);
+
+#endif /* GTM_RWLOCK_H */
=== libitm/config/linux/x86	(new directory)
==================================================================
--- libitm/config/linux/x86/futex_bits.h	(revision 141843)
+++ libitm/config/linux/x86/futex_bits.h	(local)
@@ -0,0 +1,96 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#ifdef __LP64__
+# ifndef SYS_futex
+#  define SYS_futex	202
+# endif
+
+static inline long
+sys_futex0 (int *addr, long op, long val)
+{
+  long res;
+
+  __asm volatile ("syscall"
+		  : "=a" (res)
+		  : "0" (SYS_futex), "D" (addr), "S" (op), "d" (val)
+		  : "r11", "rcx", "memory");
+
+  return res;
+}
+
+#else
+# ifndef SYS_futex
+#  define SYS_futex	240
+# endif
+
+# ifdef __PIC__
+
+static inline long
+sys_futex0 (int *addr, int op, int val)
+{
+  long res;
+
+  __asm volatile ("xchgl\t%%ebx, %2\n\t"
+		  "int\t$0x80\n\t"
+		  "xchgl\t%%ebx, %2"
+		  : "=a" (res)
+		  : "0"(SYS_futex), "r" (addr), "c"(op),
+		    "d"(val), "S"(0)
+		  : "memory");
+  return res;
+}
+
+# else
+
+static inline long
+sys_futex0 (int *addr, int op, int val)
+{
+  long res;
+
+  __asm volatile ("int $0x80"
+		  : "=a" (res)
+		  : "0"(SYS_futex), "b" (addr), "c"(op),
+		    "d"(val), "S"(0)
+		  : "memory");
+  return res;
+}
+
+# endif /* __PIC__ */
+#endif /* __LP64__ */
+
+static inline void
+cpu_relax (void)
+{
+  __asm volatile ("rep; nop" : : : "memory");
+}
+
+static inline void
+atomic_write_barrier (void)
+{
+  __sync_synchronize ();
+}
=== libitm/config/x86	(new directory)
==================================================================
--- libitm/config/x86/sjlj.S	(revision 141843)
+++ libitm/config/x86/sjlj.S	(local)
@@ -0,0 +1,108 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+	.text
+	.p2align 4
+	.globl	_ITM_beginTransaction
+	.type	_ITM_beginTransaction, @function
+
+_ITM_beginTransaction:
+	.cfi_startproc
+#ifdef __LP64__
+	leaq	8(%rsp), %rax
+	movq	(%rsp), %r8
+	subq	$72, %rsp
+	.cfi_def_cfa_offset 80
+	movq	%rax, (%rsp)
+	movq	%r8, 8(%rsp)
+	movq	%rbx, 16(%rsp)
+	movq	%rbp, 24(%rsp)
+	movq	%r12, 32(%rsp)
+	movq	%r13, 40(%rsp)
+	movq	%r14, 48(%rsp)
+	movq	%r15, 56(%rsp)
+	movq	%rsp, %rsi
+	call	GTM_begin_transaction
+	addq	$72, %rsp
+	.cfi_def_cfa_offset 8
+	ret
+#else
+	leal	4(%esp), %ecx
+	subl	$28, %esp
+	.cfi_def_cfa_offset 32
+	movl	%ecx, 8(%esp)
+	movl	%ebx, 12(%esp)
+	movl	%esi, 16(%esp)
+	movl	%edi, 20(%esp)
+	movl	%ebp, 24(%esp)
+	leal	8(%esp), %edx
+	call	GTM_begin_transaction
+	addl	$28, %esp
+	.cfi_def_cfa_offset 4
+	ret
+#endif
+	.cfi_endproc
+	.size	_ITM_beginTransaction, .-_ITM_beginTransaction
+
+	.p2align 4
+	.globl	GTM_longjmp
+	.type	GTM_longjmp, @function
+	.hidden	GTM_longjmp
+
+GTM_longjmp:
+	.cfi_startproc
+#ifdef __LP64__
+	movq	(%rsi), %rcx
+	movq	8(%rsi), %rdx
+	movq	16(%rsi), %rbx
+	movq	24(%rsi), %rbp
+	movq	32(%rsi), %r12
+	movq	40(%rsi), %r13
+	movq	48(%rsi), %r14
+	movq	56(%rsi), %r15
+	movl	%edi, %eax
+	.cfi_def_cfa %rcx, 0
+	.cfi_register %rip, %rdx
+	movq	%rcx, %rsp
+	jmp	*%rdx
+#else
+	xchgl	%eax, %edx
+	movl	(%edx), %ecx
+	movl	4(%edx), %ebx
+	movl	8(%edx), %esi
+	movl	12(%edx), %edi
+	movl	16(%edx), %ebp
+	movl	20(%edx), %edx
+	.cfi_def_cfa %ecx, 0
+	.cfi_register %eip, %edx
+	movl	%ecx, %esp
+	jmp	*%edx
+#endif
+	.cfi_endproc
+	.size	GTM_longjmp, .-GTM_longjmp
+
+.section .note.GNU-stack, "", @progbits
--- libitm/config/x86/target.h	(revision 141843)
+++ libitm/config/x86/target.h	(local)
@@ -0,0 +1,46 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#ifdef __LP64__
+
+struct gtm_jmpbuf
+{
+  unsigned long cfa;
+  unsigned long i[7];
+};
+
+#else
+
+struct gtm_jmpbuf
+{
+  unsigned long cfa;
+  unsigned long i[5];
+};
+
+#define REGPARM		__attribute__((regparm(2)))
+
+#endif
--- libitm/configure.ac	(revision 141843)
+++ libitm/configure.ac	(local)
@@ -0,0 +1,245 @@
+# Process this file with autoconf to produce a configure script, like so:
+# aclocal -I ../config && autoconf && autoheader && automake
+
+AC_PREREQ(2.59)
+AC_INIT([GNU TM Runtime Library], 1.0,,[libitm])
+AC_CONFIG_HEADER(config.h)
+
+# -------
+# Options
+# -------
+
+AC_MSG_CHECKING([for --enable-version-specific-runtime-libs])
+LIBITM_ENABLE(version-specific-runtime-libs, no, ,
+   [Specify that runtime libraries should be installed in a compiler-specific directory],
+   permit yes|no)
+AC_MSG_RESULT($enable_version_specific_runtime_libs)
+
+# We would like our source tree to be readonly. However when releases or
+# pre-releases are generated, the flex/bison generated files as well as the
+# various formats of manuals need to be included along with the rest of the
+# sources.  Therefore we have --enable-generated-files-in-srcdir to do 
+# just that.
+AC_MSG_CHECKING([for --enable-generated-files-in-srcdir])
+LIBITM_ENABLE(generated-files-in-srcdir, no, ,
+   [put copies of generated files in source dir intended for creating source 
+    tarballs for users without texinfo bison or flex.],
+   permit yes|no)
+AC_MSG_RESULT($enable_generated_files_in_srcdir)
+AM_CONDITIONAL(GENINSRC, test "$enable_generated_files_in_srcdir" = yes)
+
+
+# -------
+# -------
+
+# Gets build, host, target, *_vendor, *_cpu, *_os, etc.
+#
+# You will slowly go insane if you do not grok the following fact:  when
+# building this library, the top-level /target/ becomes the library's /host/.
+#
+# configure then causes --target to default to --host, exactly like any
+# other package using autoconf.  Therefore, 'target' and 'host' will
+# always be the same.  This makes sense both for native and cross compilers
+# just think about it for a little while.  :-)
+#
+# Also, if this library is being configured as part of a cross compiler, the
+# top-level configure script will pass the "real" host as $with_cross_host.
+#
+# Do not delete or change the following two lines.  For why, see
+# http://gcc.gnu.org/ml/libstdc++/2003-07/msg00451.html
+AC_CANONICAL_SYSTEM
+target_alias=${target_alias-$host_alias}
+
+# Sets up automake.  Must come after AC_CANONICAL_SYSTEM.  Each of the
+# following is magically included in AUTOMAKE_OPTIONS in each Makefile.am.
+#  1.9.0:  minimum required version
+#  no-define:  PACKAGE and VERSION will not be #define'd in config.h (a bunch
+#              of other PACKAGE_* variables will, however, and there's nothing
+#              we can do about that; they come from AC_INIT).
+#  foreign:  we don't follow the normal rules for GNU packages (no COPYING
+#            file in the top srcdir, etc, etc), so stop complaining.
+#  -Wall:  turns on all automake warnings...
+#  -Wno-portability:  ...except this one, since GNU make is required.
+#  -Wno-override: ... and this one, since we do want this in testsuite.
+AM_INIT_AUTOMAKE([1.9.0 foreign -Wall -Wno-portability -Wno-override])
+AM_ENABLE_MULTILIB(, ..)
+
+# 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
+AC_SUBST(toolexecdir)
+AC_SUBST(toolexeclibdir)
+
+# Check the compiler.
+# The same as in boehm-gc and libstdc++. Have to borrow it from there.
+# We must force CC to /not/ be precious variables; otherwise
+# the wrong, non-multilib-adjusted value will be used in multilibs.
+# As a side effect, we have to subst CFLAGS ourselves.
+
+m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
+m4_define([_AC_ARG_VAR_PRECIOUS],[])
+AC_PROG_CC
+m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
+
+AC_SUBST(CFLAGS)
+
+# In order to override CFLAGS_FOR_TARGET, all of our special flags go
+# in XCFLAGS.  But we need them in CFLAGS during configury.  So put them
+# in both places for now and restore CFLAGS at the end of config.
+save_CFLAGS="$CFLAGS"
+
+# Add -Wall -Werror if we are using GCC.
+if test "x$GCC" = "xyes"; then
+  XCFLAGS="$XCFLAGS -Wall -Werror"
+fi
+
+# Find other programs we need.
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(RANLIB, ranlib, ranlib-not-found-in-path-error)
+AC_PATH_PROG(PERL, perl, perl-not-found-in-path-error)
+AC_PROG_MAKE_SET
+AC_PROG_INSTALL
+
+# See if makeinfo has been installed and is modern enough
+# that we can use it.
+ACX_CHECK_PROG_VER([MAKEINFO], [makeinfo], [--version],
+                   [GNU texinfo.* \([0-9][0-9.]*\)],
+                   [4.[4-9]*|4.[1-9][0-9]*|[5-9]*|[1-9][0-9]*])
+AM_CONDITIONAL(BUILD_INFO, test $gcc_cv_prog_makeinfo_modern = "yes")
+
+
+# Configure libtool
+AM_PROG_LIBTOOL
+AC_SUBST(enable_shared)
+AC_SUBST(enable_static)
+
+AM_MAINTAINER_MODE
+
+# We need gfortran to compile parts of the library
+# We can't use AC_PROG_FC because it expects a fully working gfortran.
+#AC_PROG_FC(gfortran)
+FC="$GFORTRAN"
+AC_PROG_FC(gfortran)
+FCFLAGS="$FCFLAGS -Wall"
+
+# For libtool versioning info, format is CURRENT:REVISION:AGE
+libtool_VERSION=1:0:0
+AC_SUBST(libtool_VERSION)
+
+# Check header files.
+AC_STDC_HEADERS
+AC_HEADER_TIME
+ACX_HEADER_STRING
+AC_CHECK_HEADERS(unistd.h semaphore.h sys/loadavg.h sys/time.h sys/time.h)
+
+GCC_HEADER_STDINT(gstdint.h)
+
+# Check to see if -pthread or -lpthread is needed.  Prefer the former.
+# In case the pthread.h system header is not found, this test will fail.
+# ??? Not needed if linux futexes are used.
+XPCFLAGS=""
+CFLAGS="$CFLAGS -pthread"
+AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+  [#include <pthread.h>
+   void *g(void *d) { return NULL; }],
+  [pthread_t t; pthread_create(&t,NULL,g,NULL);])],
+ [XPCFLAGS=" -Wc,-pthread"],
+ [CFLAGS="$save_CFLAGS" LIBS="-lpthread $LIBS"
+  AC_LINK_IFELSE(
+   [AC_LANG_PROGRAM(
+    [#include <pthread.h>
+     void *g(void *d) { return NULL; }],
+    [pthread_t t; pthread_create(&t,NULL,g,NULL);])],
+   [],
+   [AC_MSG_ERROR([Pthreads are required to build libitm])])])
+
+# Check for functions needed.
+AC_CHECK_FUNCS(getloadavg clock_gettime strtoull)
+
+# Check for broken semaphore implementation on darwin.
+# sem_init returns: sem_init error: Function not implemented.
+case "$host" in
+  *-darwin*)
+    AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1,
+	Define if the POSIX Semaphores do not work on your system.)
+    ;;
+esac
+
+GCC_LINUX_FUTEX(:)
+
+# See if we support thread-local storage.
+GCC_CHECK_TLS
+
+# See what sort of export controls are availible.
+LIBITM_CHECK_ATTRIBUTE_VISIBILITY
+LIBITM_CHECK_ATTRIBUTE_DLLEXPORT
+LIBITM_CHECK_ATTRIBUTE_ALIAS
+LIBITM_ENABLE_SYMVERS
+
+if test $enable_symvers = gnu; then
+  AC_DEFINE(LIBITM_GNU_SYMBOL_VERSIONING, 1,
+	    [Define to 1 if GNU symbol versioning is used for libitm.])
+fi
+
+# Get target configury.
+. ${srcdir}/configure.tgt
+CFLAGS="$save_CFLAGS $XCFLAGS"
+
+# Check for __sync_val_compare_and_swap, but only after the target has
+# had a chance to set XCFLAGS.
+LIBITM_CHECK_SYNC_BUILTINS
+
+XCFLAGS="$XCFLAGS$XPCFLAGS"
+
+AC_SUBST(config_path)
+AC_SUBST(XCFLAGS)
+AC_SUBST(XLDFLAGS)
+
+# Cleanup and exit.
+CFLAGS="$save_CFLAGS"
+AC_CACHE_SAVE
+
+if test ${multilib} = yes; then
+  multilib_arg="--enable-multilib"
+else
+  multilib_arg=
+fi
+
+# Set up the set of libraries that we need to link against for libitm.
+# Note that the GOMP_SELF_SPEC in gcc.c will force -pthread for -fopenmp,
+# which will force linkage against -lpthread (or equivalent for the system).
+# That's not 100% ideal, but about the best we can do easily.
+if test $enable_shared = yes; then
+  link_itm="-litm %{static: $LIBS}"
+else
+  link_itm="-litm $LIBS"
+fi
+AC_SUBST(link_itm)
+
+AC_CONFIG_FILES(Makefile libitm.spec)
+AC_OUTPUT
--- libitm/configure.tgt	(revision 141843)
+++ libitm/configure.tgt	(local)
@@ -0,0 +1,121 @@
+# This is the target specific configuration file.  This is invoked by the
+# autoconf generated configure script.  Putting it in a separate shell file
+# lets us skip running autoconf when modifying target specific information.
+
+# This file switches on the shell variable ${target}, and sets the
+# following shell variables:
+#  config_path		An ordered list of directories to search for
+#			sources and headers.  This is relative to the
+#			config subdirectory of the source tree.
+#  XCFLAGS		Add extra compile flags to use.
+#  XLDFLAGS		Add extra link flags to use.
+
+# Optimize TLS usage by avoiding the overhead of dynamic allocation.
+if test $gcc_cv_have_tls = yes ; then
+  case "${target}" in
+
+    *-*-linux*)
+	XCFLAGS="${XCFLAGS} -ftls-model=initial-exec"
+	;;
+  esac
+fi
+
+# Since we require POSIX threads, assume a POSIX system by default.
+config_path="posix"
+
+# Check for futex enabled all at once.
+if test $enable_linux_futex = yes; then
+  case "${target}" in
+
+    alpha*-*-linux*)
+	config_path="linux/alpha linux alpha posix"
+	;;
+
+    ia64*-*-linux*)
+	config_path="linux/ia64 linux ia64 posix"
+	;;
+
+    mips*-*-linux*)
+	config_path="linux/mips linux mips posix"
+	;;
+
+    powerpc*-*-linux*)
+	config_path="linux/powerpc linux powerpc posix"
+	;;
+
+    s390*-*-linux*)
+	config_path="linux/s390 linux s390 posix"
+	;;
+
+    # Note that bare i386 is not included here.  We need cmpxchg.
+    i[456]86-*-linux*)
+	config_path="linux/x86 linux x86 posix"
+	case " ${CC} ${CFLAGS} " in
+	  *" -m64 "*)
+	    ;;
+	  *)
+	    if test -z "$with_arch"; then
+	      XCFLAGS="${XCFLAGS} -march=i486 -msse2 -mtune=${target_cpu}"
+	    fi
+	esac
+	;;
+
+    # Similar jiggery-pokery for x86_64 multilibs, except here we
+    # can't rely on the --with-arch configure option, since that
+    # applies to the 64-bit side.
+    x86_64-*-linux*)
+	config_path="linux/x86 linux x86 posix"
+	case " ${CC} ${CFLAGS} " in
+	  *" -m32 "*)
+	    XCFLAGS="${XCFLAGS} -march=i486 -msse2 -mtune=i686"
+	    ;;
+	esac
+	;;
+
+    # Note that sparcv7 and sparcv8 is not included here.  We need cas.
+    sparcv9-*-linux* | sparc64-*-linux*)
+	echo "int i;" > conftestx.c
+	if ${CC} ${CFLAGS} -c -o conftestx.o conftestx.c > /dev/null 2>&1; then
+	  config_path="linux/sparc linux sparc posix"
+	  case "`/usr/bin/file conftestx.o`" in
+	    *32-bit*)
+	      case " ${CC} ${CFLAGS}" in
+		*" -mcpu=ultrasparc"*)
+		  ;;
+		*)
+		  XCFLAGS="${XCFLAGS} -mcpu=v9"
+		  ;;
+	      esac
+	      ;;
+	  esac
+	fi
+	rm -f conftestx.c conftestx.o
+	;;
+  esac
+fi
+
+# Other system configury
+case "${target}" in
+
+  *-*-hpux11*)
+	# HPUX v11.x requires -lrt to resolve sem_init in libgomp.la
+	XLDFLAGS="${XLDFLAGS} -lrt"
+	;;
+
+  *-*-mingw32*)
+	config_path="mingw32 posix"
+	;;
+
+  *-*-solaris2.[56]*)
+	config_path="posix95 posix"
+	XLDFLAGS="${XLDFLAGS} -lposix4"
+	;;
+
+  *-*-darwin*)
+	config_path="bsd posix"
+	;;
+
+  *)
+	;;
+
+esac
--- libitm/dispatch.c	(revision 141843)
+++ libitm/dispatch.c	(local)
@@ -0,0 +1,68 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#include "libitm.h"
+
+
+#define _ITM_READ(R, T) \
+_ITM_TYPE_##T REGPARM _ITM_##R##T(const _ITM_TYPE_##T *ptr)		\
+{									\
+  return gtm_thr.disp->R##T (ptr);					\
+}
+
+#define _ITM_WRITE(W, T) \
+void REGPARM _ITM_##W##T(_ITM_TYPE_##T *ptr, _ITM_TYPE_##T val)		\
+{									\
+  gtm_thr.disp->W##T (ptr, val);					\
+}
+
+_ITM_ALL_TYPES (_ITM_ALL_READS)
+_ITM_ALL_TYPES (_ITM_ALL_WRITES)
+
+#undef _ITM_READ
+#undef _ITM_WRITE
+
+#define _ITM_MCPY_RW(FN, R, W) \
+void REGPARM _ITM_##FN##R##W (void *dst, const void *src, size_t len)	\
+{									\
+  gtm_thr.disp->FN##R##W (dst, src, len);				\
+}
+
+_ITM_MCPY(memcpy)
+_ITM_MCPY(memmove)
+
+#undef _ITM_MCPY_RW
+
+#define _ITM_MSET_W(FN, W) \
+void REGPARM _ITM_##FN##W (void *dst, int src, size_t len)		\
+{									\
+  gtm_thr.disp->FN##W (dst, src, len);					\
+}
+
+_ITM_MSET(memset)
+
+#undef _ITM_MSET_W
--- libitm/libitm.h	(revision 141843)
+++ libitm/libitm.h	(local)
@@ -0,0 +1,348 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+/* The external interface of this library follows the specification described
+   in version 1 of http://www.intel.com/some/path/here.pdf.  */
+
+#ifndef LIBITM_H
+#define LIBITM_H 1
+
+#include "config.h"
+#include "target.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef REGPARM
+# define REGPARM
+#endif
+
+#define NORETURN	__attribute__((noreturn))
+#define UNUSED		__attribute__((unused))
+
+/* The following are externally visible definitions and functions, though
+   only very few of these should be called by user code.  */
+/* ??? Move declarations usable by user code to another header; figure out
+   how to unobtrusively define REGPARM there.  */
+
+/* Values used as arguments to abort. */
+typedef enum {
+    userAbort = 1,
+    userRetry = 2,
+    TMConflict= 4,
+    exceptionBlockAbort = 8
+} _ITM_abortReason;
+
+/* Arguments to changeTransactionMode */
+typedef enum
+{
+    modeSerialIrrevocable,
+} _ITM_transactionState;
+
+/* Results from inTransaction */
+typedef enum
+{
+    outsideTransaction = 0,    /* So "if (inTransaction(td))" works */
+    inRetryableTransaction,
+    inIrrevocableTransaction
+} _ITM_howExecuting;
+
+/* Values to describe properties of code, passed in to startTransaction */
+typedef enum
+{
+   pr_instrumentedCode    = 0x0001,
+   pr_uninstrumentedCode  = 0x0002,
+   pr_multiwayCode        = pr_instrumentedCode | pr_uninstrumentedCode,
+   pr_hasNoXMMUpdate      = 0x0004,
+   pr_hasNoAbort          = 0x0008,
+   pr_hasNoRetry          = 0x0010,
+   pr_hasNoIrrevocable    = 0x0020,
+   pr_doesGoIrrevocable   = 0x0040,
+   pr_hasNoSimpleReads    = 0x0080,
+   pr_aWBarriersOmitted   = 0x0100,
+   pr_RaRBarriersOmitted  = 0x0200,
+   pr_undoLogCode         = 0x0400,
+   pr_preferUninstrumented=0x0800,
+   pr_exceptionBlock      = 0x1000,
+   pr_hasElse             = 0x2000,
+} _ITM_codeProperties;
+
+/* Result from startTransaction that describes what actions to take.  */
+typedef enum
+{
+   a_runInstrumentedCode       = 0x01,
+   a_runUninstrumentedCode     = 0x02,
+   a_saveLiveVariables         = 0x04,
+   a_restoreLiveVariables      = 0x08,
+   a_abortTransaction          = 0x10,
+} _ITM_actions;
+
+typedef struct
+{
+    uint32_t reserved_1;
+    uint32_t flags;
+    uint32_t reserved_2;
+    uint32_t reserved_3;
+    const char *psource;
+} _ITM_srcLocation;
+
+typedef void (* _ITM_userUndoFunction)(void *);
+typedef void (* _ITM_userCommitFunction) (void *);
+
+#define _ITM_VERSION "0.90 (Feb 29 2008)"
+#define _ITM_VERSION_NO 90
+
+extern int _ITM_versionCompatible (int) REGPARM;
+extern const char * _ITM_libraryVersion (void) REGPARM;
+
+void _ITM_error(const _ITM_srcLocation *, int errorCode) REGPARM NORETURN;
+ 
+extern _ITM_howExecuting _ITM_inTransaction(void) REGPARM;
+
+typedef uint32_t _ITM_transactionId_t;	/* Transaction identifier */
+#define _ITM_noTransactionId 1		/* Id for non-transactional code. */
+
+extern _ITM_transactionId_t _ITM_getTransactionId(void) REGPARM;
+
+extern uint32_t _ITM_beginTransaction(uint32_t, const _ITM_srcLocation *)
+	REGPARM;
+
+extern void _ITM_abortTransaction(_ITM_abortReason,
+	const _ITM_srcLocation *) REGPARM NORETURN;
+extern void _ITM_rollbackTransaction (const _ITM_srcLocation *) REGPARM;
+
+extern void _ITM_commitTransaction (const _ITM_srcLocation *) REGPARM;
+extern bool _ITM_tryCommitTransaction(const _ITM_srcLocation *) REGPARM;
+
+extern void _ITM_changeTransactionMode (_ITM_transactionState,
+					const _ITM_srcLocation *) REGPARM;
+
+/* The following typedefs exist to make the macro expansions below work
+   properly.  They are not part of any API.  */
+typedef uint8_t  _ITM_TYPE_U1;
+typedef uint16_t _ITM_TYPE_U2;
+typedef uint32_t _ITM_TYPE_U4;
+typedef uint64_t _ITM_TYPE_U8;
+typedef float    _ITM_TYPE_F;
+typedef double   _ITM_TYPE_D;
+typedef long double _ITM_TYPE_E;
+typedef float _Complex _ITM_TYPE_CF;
+typedef double _Complex _ITM_TYPE_CD;
+typedef long double _Complex _ITM_TYPE_CE;
+
+/* ??? These are really specific to i386.  Work out some way to handle
+   platform-specific vectors, assuming U8 doesn't fit the bill.  */
+typedef int _ITM_TYPE_M64
+  __attribute__ ((__vector_size__ (8), __may_alias__));
+typedef float _ITM_TYPE_M128
+  __attribute__ ((__vector_size__ (16), __may_alias__));
+typedef float _ITM_TYPE_M256
+  __attribute__ ((__vector_size__ (32), __may_alias__));
+
+#define _ITM_READ(R, T) \
+  extern _ITM_TYPE_##T _ITM_##R##T (const _ITM_TYPE_##T *) REGPARM;
+#define _ITM_WRITE(W, T) \
+  extern void _ITM_##W##T (_ITM_TYPE_##T *, _ITM_TYPE_##T) REGPARM;
+
+#define _ITM_ALL_READS(T) \
+  _ITM_READ(R, T) _ITM_READ(RaR, T) _ITM_READ(RaW, T) _ITM_READ(RfW, T)
+#define _ITM_ALL_WRITES(T) \
+  _ITM_WRITE(W, T) _ITM_WRITE(WaR, T) _ITM_WRITE(WaW, T)
+
+#define _ITM_ALL_TYPES(M) \
+  M(U1) M(U2) M(U4) M(U8) M(F) M(D) M(E) \
+  M(CF) M(CD) M(CE) M(M64) M(M128) M(M256)
+
+_ITM_ALL_TYPES(_ITM_ALL_READS)
+_ITM_ALL_TYPES(_ITM_ALL_WRITES)
+
+#define _ITM_LOG(T) \
+  extern void _ITM_L##T (const _ITM_TYPE_##T *) REGPARM;
+
+_ITM_ALL_TYPES(_ITM_LOG)
+
+#undef _ITM_READ
+#undef _ITM_WRITE
+
+#define _ITM_MCPY_RW(FN, R, W) \
+  extern void _ITM_##FN##R##W (void *, const void *, size_t) REGPARM;
+#define _ITM_MCPY_Wt(FN, R) \
+  _ITM_MCPY_RW(FN,R,Wt) _ITM_MCPY_RW(FN,R,WtaR) _ITM_MCPY_RW(FN,R,WtaW)
+#define _ITM_MCPY(FN) \
+  _ITM_MCPY_Wt(FN, Rn) \
+  _ITM_MCPY_Wt(FN, Rt) \
+  _ITM_MCPY_Wt(FN, RtaR) \
+  _ITM_MCPY_Wt(FN, RtaW) \
+  _ITM_MCPY_RW(FN, Rt, Wn) \
+  _ITM_MCPY_RW(FN, RtaR, Wn) \
+  _ITM_MCPY_RW(FN, RtaW, Wn)
+
+_ITM_MCPY(memcpy)
+_ITM_MCPY(memmove)
+
+#undef _ITM_MCPY_RW
+
+#define _ITM_MSET_W(FN, W) \
+  extern void _ITM_##FN##W (void * target, int src, size_t count) REGPARM;
+#define _ITM_MSET(FN) \
+  _ITM_MSET_W(FN, W) _ITM_MSET_W(FN, WaR) _ITM_MSET_W(FN, WaW)
+
+_ITM_MSET (memset)
+
+#undef _ITM_MSET_W
+
+extern void _ITM_LB (const void *, size_t) REGPARM;
+
+extern void _ITM_addUserCommitAction(_ITM_userCommitFunction,
+				     _ITM_transactionId_t, void *) REGPARM;
+
+extern void _ITM_addUserUndoAction(_ITM_userUndoFunction, void *) REGPARM;
+
+extern int _ITM_getThreadnum(void) REGPARM;
+
+extern void _ITM_dropReferences (const void *, size_t) REGPARM;
+
+/* The following are internal implementation functions and definitions.
+   To distinguish them from those defined by the Intel ABI, they all
+   begin with GTM/gtm.  */
+
+#ifdef HAVE_ATTRIBUTE_VISIBILITY
+# pragma GCC visibility push(hidden)
+#endif
+
+#include "rwlock.h"
+
+
+/* ??? We're talking about storing some of this data in glibc tls slots
+   begining at 10, and making this part of the ABI on Linux.  Think about
+   how to declare such things.  */
+   
+struct gtm_dispatch
+{
+#define _ITM_READ(R, T) \
+  _ITM_TYPE_##T (*R##T)(const _ITM_TYPE_##T *) REGPARM;
+#define _ITM_WRITE(W, T) \
+  void (*W##T)(_ITM_TYPE_##T *, _ITM_TYPE_##T) REGPARM;
+  _ITM_ALL_TYPES (_ITM_ALL_READS)
+  _ITM_ALL_TYPES (_ITM_ALL_WRITES)
+#undef _ITM_READ
+#undef _ITM_WRITE
+
+#define _ITM_MCPY_RW(FN, R, W) \
+  void (* FN##R##W)(void *, const void *, size_t) REGPARM;
+  _ITM_MCPY(memcpy)
+  _ITM_MCPY(memmove)
+#undef _ITM_MCPY_RW
+
+#define _ITM_MSET_W(FN, W) \
+  void (*FN##W) (void *, int, size_t) REGPARM;
+  _ITM_MSET(memset)
+#undef _ITM_MSET_W
+
+  bool (*trycommit) (void);
+  void (*rollback) (void);
+};
+
+struct gtm_local_undo
+{
+  void *addr;
+  size_t len;
+  char saved[];
+};
+
+struct gtm_user_action
+{
+  struct gtm_user_action *next;
+  _ITM_userCommitFunction fn;
+  void *arg;
+};
+
+#define STATE_READONLY		0x0001
+#define STATE_SERIAL		0x0002
+#define STATE_IRREVOKABLE	0x0004
+#define STATE_ABORTING		0x0008
+
+struct gtm_transaction
+{
+  uint32_t prop;
+  uint32_t nesting;
+  uint32_t state;
+  uint32_t id;
+
+  struct gtm_jmpbuf jb;
+
+  struct gtm_local_undo **local_undo;
+  size_t n_local_undo;
+  size_t size_local_undo;
+
+  struct gtm_user_action *commit_actions;
+  struct gtm_user_action *undo_actions;
+
+  struct gtm_transaction *prev;
+};
+
+#define MAX_FREE_TX	8
+
+struct gtm_thread
+{
+  struct gtm_transaction *tx;
+  const struct gtm_dispatch *disp;
+
+  struct gtm_transaction *free_tx[MAX_FREE_TX];
+  unsigned free_tx_idx, free_tx_count;
+
+  int thread_num;
+};
+
+extern __thread struct gtm_thread gtm_thr;
+
+extern gtm_rwlock gtm_serial_lock;
+extern unsigned long long gtm_spin_count_var;
+
+extern uint32_t GTM_begin_transaction(uint32_t, const struct gtm_jmpbuf *)
+	REGPARM;
+
+extern uint32_t GTM_longjmp (const struct gtm_jmpbuf *, uint32_t)
+	REGPARM NORETURN;
+
+extern void GTM_commit_local (void);
+extern void GTM_rollback_local (void);
+
+extern void GTM_serialmode (bool) REGPARM;
+extern void GTM_decide_retry_strategy (void);
+
+extern void GTM_run_actions (struct gtm_user_action **) REGPARM;
+extern void GTM_free_actions (struct gtm_user_action **) REGPARM;
+
+#ifdef HAVE_ATTRIBUTE_VISIBILITY
+# pragma GCC visibility pop
+#endif
+
+#endif /* LIBITM_H */
--- libitm/libitm.map	(revision 141843)
+++ libitm/libitm.map	(local)
@@ -0,0 +1,162 @@
+LIBITM_1.0 {
+  global:
+	_ITM_abortTransaction;
+	_ITM_addUserCommitAction;
+	_ITM_addUserUndoAction;
+	_ITM_beginTransaction;
+	_ITM_changeTransactionMode;
+	_ITM_commitTransaction;
+	_ITM_error;
+	_ITM_getThreadnum;
+	_ITM_getTransactionId;
+	_ITM_inTransaction;
+	_ITM_libraryVersion;
+	_ITM_rollbackTransaction;
+	_ITM_tryCommitTransaction;
+	_ITM_versionCompatible;
+
+	_ITM_LB;
+	_ITM_LCD;
+	_ITM_LCE;
+	_ITM_LCF;
+	_ITM_LD;
+	_ITM_LE;
+	_ITM_LF;
+	_ITM_LM128;
+	_ITM_LM256;
+	_ITM_LM64;
+	_ITM_LU1;
+	_ITM_LU2;
+	_ITM_LU4;
+	_ITM_LU8;
+
+	_ITM_RCD;
+	_ITM_RCE;
+	_ITM_RCF;
+	_ITM_RD;
+	_ITM_RE;
+	_ITM_RF;
+	_ITM_RM128;
+	_ITM_RM256;
+	_ITM_RM64;
+	_ITM_RU1;
+	_ITM_RU2;
+	_ITM_RU4;
+	_ITM_RU8;
+	_ITM_RaRCD;
+	_ITM_RaRCE;
+	_ITM_RaRCF;
+	_ITM_RaRD;
+	_ITM_RaRE;
+	_ITM_RaRF;
+	_ITM_RaRM128;
+	_ITM_RaRM256;
+	_ITM_RaRM64;
+	_ITM_RaRU1;
+	_ITM_RaRU2;
+	_ITM_RaRU4;
+	_ITM_RaRU8;
+	_ITM_RaWCD;
+	_ITM_RaWCE;
+	_ITM_RaWCF;
+	_ITM_RaWD;
+	_ITM_RaWE;
+	_ITM_RaWF;
+	_ITM_RaWM128;
+	_ITM_RaWM256;
+	_ITM_RaWM64;
+	_ITM_RaWU1;
+	_ITM_RaWU2;
+	_ITM_RaWU4;
+	_ITM_RaWU8;
+	_ITM_RfWCD;
+	_ITM_RfWCE;
+	_ITM_RfWCF;
+	_ITM_RfWD;
+	_ITM_RfWE;
+	_ITM_RfWF;
+	_ITM_RfWM128;
+	_ITM_RfWM256;
+	_ITM_RfWM64;
+	_ITM_RfWU1;
+	_ITM_RfWU2;
+	_ITM_RfWU4;
+	_ITM_RfWU8;
+
+	_ITM_WCD;
+	_ITM_WCE;
+	_ITM_WCF;
+	_ITM_WD;
+	_ITM_WE;
+	_ITM_WF;
+	_ITM_WM128;
+	_ITM_WM256;
+	_ITM_WM64;
+	_ITM_WU1;
+	_ITM_WU2;
+	_ITM_WU4;
+	_ITM_WU8;
+	_ITM_WaRCD;
+	_ITM_WaRCE;
+	_ITM_WaRCF;
+	_ITM_WaRD;
+	_ITM_WaRE;
+	_ITM_WaRF;
+	_ITM_WaRM128;
+	_ITM_WaRM256;
+	_ITM_WaRM64;
+	_ITM_WaRU1;
+	_ITM_WaRU2;
+	_ITM_WaRU4;
+	_ITM_WaRU8;
+	_ITM_WaWCD;
+	_ITM_WaWCE;
+	_ITM_WaWCF;
+	_ITM_WaWD;
+	_ITM_WaWE;
+	_ITM_WaWF;
+	_ITM_WaWM128;
+	_ITM_WaWM256;
+	_ITM_WaWM64;
+	_ITM_WaWU1;
+	_ITM_WaWU2;
+	_ITM_WaWU4;
+	_ITM_WaWU8;
+
+	_ITM_memcpyRnWt;
+	_ITM_memcpyRnWtaR;
+	_ITM_memcpyRnWtaW;
+	_ITM_memcpyRtWn;
+	_ITM_memcpyRtWt;
+	_ITM_memcpyRtWtaR;
+	_ITM_memcpyRtWtaW;
+	_ITM_memcpyRtaRWn;
+	_ITM_memcpyRtaRWt;
+	_ITM_memcpyRtaRWtaR;
+	_ITM_memcpyRtaRWtaW;
+	_ITM_memcpyRtaWWn;
+	_ITM_memcpyRtaWWt;
+	_ITM_memcpyRtaWWtaR;
+	_ITM_memcpyRtaWWtaW;
+	_ITM_memmoveRnWt;
+	_ITM_memmoveRnWtaR;
+	_ITM_memmoveRnWtaW;
+	_ITM_memmoveRtWn;
+	_ITM_memmoveRtWt;
+	_ITM_memmoveRtWtaR;
+	_ITM_memmoveRtWtaW;
+	_ITM_memmoveRtaRWn;
+	_ITM_memmoveRtaRWt;
+	_ITM_memmoveRtaRWtaR;
+	_ITM_memmoveRtaRWtaW;
+	_ITM_memmoveRtaWWn;
+	_ITM_memmoveRtaWWt;
+	_ITM_memmoveRtaWWtaR;
+	_ITM_memmoveRtaWWtaW;
+	_ITM_memsetW;
+	_ITM_memsetWaR;
+	_ITM_memsetWaW;
+
+  local:
+	*;
+};
--- libitm/libitm.spec.in	(revision 141843)
+++ libitm/libitm.spec.in	(local)
@@ -0,0 +1,3 @@
+# This spec file is read by gcc when linking.  It is used to specify the
+# standard libraries we need in order to link with -fgnu-tm
+*link_itm: @link_itm@
--- libitm/local.c	(revision 141843)
+++ libitm/local.c	(local)
@@ -0,0 +1,114 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#include "libitm.h"
+
+
+void
+GTM_commit_local (void)
+{
+  struct gtm_transaction *tx = gtm_thr.tx;
+  struct gtm_local_undo **local_undo = tx->local_undo;
+  size_t i, n = tx->n_local_undo;
+
+  if (n > 0)
+    {
+      for (i = 0; i < n; ++i)
+	free (local_undo[i]);
+      tx->n_local_undo = 0;
+    }
+  if (local_undo)
+    {
+      free (local_undo);
+      tx->local_undo = NULL;
+      tx->size_local_undo = 0;
+    }
+}
+
+static void
+rollback_local (struct gtm_local_undo *undo)
+{
+  memcpy (undo->addr, undo->saved, undo->len);
+}
+
+void
+GTM_rollback_local (void)
+{
+  struct gtm_transaction *tx = gtm_thr.tx;
+  struct gtm_local_undo **local_undo = tx->local_undo;
+  size_t i, n = tx->n_local_undo;
+
+  if (n > 0)
+    {
+      for (i = n; i-- > 0; )
+	{
+	  rollback_local (local_undo[i]);
+	  free (local_undo[i]);
+	}
+      tx->n_local_undo = 0;
+    }
+}
+
+static void *
+alloc_local (void *addr, size_t len)
+{
+  struct gtm_transaction *tx = gtm_thr.tx;
+  struct gtm_local_undo *undo;
+
+  undo = malloc (sizeof (struct gtm_local_undo) + len);
+  undo->addr = addr;
+  undo->len = len;
+
+  if (tx->local_undo == NULL)
+    {
+      tx->size_local_undo = 32;
+      tx->local_undo = malloc (sizeof (undo) * tx->size_local_undo);
+    }
+  else if (tx->n_local_undo == tx->size_local_undo)
+    {
+      tx->size_local_undo *= 2;
+      tx->local_undo = realloc (tx->local_undo,
+				sizeof (undo) * tx->size_local_undo);
+    }
+  tx->local_undo[tx->n_local_undo++] = undo;
+
+  return undo->saved;
+}
+
+#define _ITM_LOG_DEF(T)							\
+void REGPARM _ITM_L##T (const _ITM_TYPE_##T *ptr)			\
+{									\
+  *(_ITM_TYPE_##T *)alloc_local((void *)ptr, sizeof(_ITM_TYPE_##T)) = *ptr; \
+}
+
+_ITM_ALL_TYPES(_ITM_LOG_DEF)
+
+void REGPARM
+_ITM_LB (const void *ptr, size_t len)
+{
+  memcpy(alloc_local ((void *)ptr, len), ptr, len);
+}
--- libitm/query.c	(revision 141843)
+++ libitm/query.c	(local)
@@ -0,0 +1,88 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#include "libitm.h"
+
+
+int REGPARM
+_ITM_versionCompatible (int version)
+{
+  return version == _ITM_VERSION_NO;
+}
+
+
+const char * REGPARM
+_ITM_libraryVersion (void)
+{
+  return "GNU libitm " _ITM_VERSION;
+}
+
+
+_ITM_howExecuting REGPARM
+_ITM_inTransaction (void)
+{
+  struct gtm_transaction *tx = gtm_thr.tx;
+  if (tx)
+    {
+      if (tx->state & STATE_IRREVOKABLE)
+	return inIrrevocableTransaction;
+      else
+	return inRetryableTransaction;
+    }
+  return outsideTransaction;
+}
+
+
+_ITM_transactionId_t REGPARM
+_ITM_getTransactionId (void)
+{
+  struct gtm_transaction *tx = gtm_thr.tx;
+  return tx ? tx->id : _ITM_noTransactionId;
+}
+
+
+int REGPARM
+_ITM_getThreadnum (void)
+{
+  static int global_num;
+  int num = gtm_thr.thread_num;
+
+  if (num == 0)
+    {
+      num = __sync_add_and_fetch (&global_num, 1);
+      gtm_thr.thread_num = num;
+    }
+
+  return num;
+}
+
+
+void REGPARM NORETURN
+_ITM_error (const _ITM_srcLocation * loc UNUSED, int errorCode UNUSED)
+{
+  abort ();
+}
--- libitm/retry.c	(revision 141843)
+++ libitm/retry.c	(local)
@@ -0,0 +1,34 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#include "libitm.h"
+
+
+void
+GTM_decide_retry_strategy (void)
+{
+}
--- libitm/serial.c	(revision 141843)
+++ libitm/serial.c	(local)
@@ -0,0 +1,115 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#include "libitm.h"
+
+
+#define SERIAL(T) \
+static _ITM_TYPE_##T REGPARM serial_R##T(const _ITM_TYPE_##T *ptr)	\
+{									\
+  return *ptr;								\
+}									\
+static void REGPARM serial_W##T(_ITM_TYPE_##T *ptr, _ITM_TYPE_##T val)	\
+{									\
+  *ptr = val;								\
+}
+
+_ITM_ALL_TYPES (SERIAL)
+
+#undef SERIAL
+
+static void REGPARM serial_memcpy (void *dst, const void *src, size_t len)
+{
+  memcpy (dst, src, len);
+}
+
+static void REGPARM serial_memmove (void *dst, const void *src, size_t len)
+{
+  memmove (dst, src, len);
+}
+
+static void REGPARM serial_memset (void *dst, int src, size_t len)
+{
+  memset (dst, src, len);
+}
+
+static bool serial_trycommit (void)
+{
+  return true;
+}
+
+static void serial_rollback (void)
+{
+  abort ();
+}
+
+const static struct gtm_dispatch serial_dispatch = 
+{
+#define _ITM_READ(R, T)		.R##T = serial_R##T,
+#define _ITM_WRITE(W, T)	.W##T = serial_W##T,
+  _ITM_ALL_TYPES (_ITM_ALL_READS)
+  _ITM_ALL_TYPES (_ITM_ALL_WRITES)
+#undef _ITM_READ
+#undef _ITM_WRITE
+
+#define _ITM_MCPY_RW(FN, R, W)	.FN##R##W = serial_##FN,
+  _ITM_MCPY(memcpy)
+  _ITM_MCPY(memmove)
+#undef _ITM_MCPY_RW
+
+#define _ITM_MSET_W(FN, W)	.FN##W = serial_##FN,
+  _ITM_MSET(memset)
+#undef _ITM_MSET_W
+
+  .trycommit = serial_trycommit,
+  .rollback = serial_rollback,
+};
+
+
+void REGPARM
+GTM_serialmode (bool initial)
+{
+  if (gtm_thr.tx->state & STATE_SERIAL)
+    return;
+
+  if (initial)
+    gtm_rwlock_write_lock (&gtm_serial_lock);
+  else
+    gtm_rwlock_write_upgrade (&gtm_serial_lock);
+
+  gtm_thr.tx->state = STATE_SERIAL | STATE_IRREVOKABLE;
+  gtm_thr.disp = &serial_dispatch;
+}
+
+
+void REGPARM
+_ITM_changeTransactionMode (_ITM_transactionState state,
+			    const _ITM_srcLocation *loc UNUSED)
+{
+  assert (state == modeSerialIrrevocable);
+  GTM_serialmode (false);
+}
=== libitm/testsuite	(new directory)
==================================================================
--- libitm/useraction.c	(revision 141843)
+++ libitm/useraction.c	(local)
@@ -0,0 +1,99 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>.
+
+   This file is part of the GNU Transactional Memory Library (libitm).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   more details.
+
+   You should have received a copy of the GNU Lesser General Public License 
+   along with libgomp; see the file COPYING.LIB.  If not, write to the
+   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files, some
+   of which are compiled with GCC, to produce an executable, this library
+   does not by itself cause the resulting executable to be covered by the
+   GNU General Public License.  This exception does not however invalidate
+   any other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#include "libitm.h"
+
+
+void REGPARM
+GTM_run_actions (struct gtm_user_action **list)
+{
+  struct gtm_user_action *a = *list;
+
+  if (a == NULL)
+    return;
+  *list = NULL;
+
+  do
+    {
+      struct gtm_user_action *n = a->next;
+      a->fn (a->arg);
+      free (a);
+      a = n;
+    }
+  while (a);
+}
+
+
+void REGPARM
+GTM_free_actions (struct gtm_user_action **list)
+{
+  struct gtm_user_action *a = *list;
+
+  if (a == NULL)
+    return;
+  *list = NULL;
+
+  do
+    {
+      struct gtm_user_action *n = a->next;
+      free (a);
+      a = n;
+    }
+  while (a);
+}
+
+
+void REGPARM
+_ITM_addUserCommitAction(_ITM_userCommitFunction fn,
+			 _ITM_transactionId_t tid, void *arg)
+{
+  struct gtm_transaction *tx;
+  struct gtm_user_action *a;
+
+  for (tx = gtm_thr.tx; tx->id != tid; tx = tx->prev)
+    continue;
+
+  a = malloc (sizeof (*a));
+  a->next = tx->commit_actions;
+  a->fn = fn;
+  a->arg = arg;
+  tx->commit_actions = a;
+}
+
+
+void REGPARM
+_ITM_addUserUndoAction(_ITM_userUndoFunction fn, void * arg)
+{
+  struct gtm_transaction *tx = gtm_thr.tx;
+  struct gtm_user_action *a;
+
+  a = malloc (sizeof (*a));
+  a->next = tx->undo_actions;
+  a->fn = fn;
+  a->arg = arg;
+  tx->undo_actions = a;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]