OSDN Git Service

* gcc.c (MFWRAP_SPEC): Don't wrap pthread_join or pthread_exit.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 17 Jul 2005 02:29:00 +0000 (02:29 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 17 Jul 2005 02:29:00 +0000 (02:29 +0000)
        * acinclude.m4: New file.
        * configure.ac: Invoke LIBMUDFLAP_CHECK_TLS.
        * configure, config.h.in, Makefile.in, testsuite/Makefile.in: Rebuild.
        * mf-hooks1.c (__mf_0fn_malloc): Move body from ...
        (__mf_0fn_calloc): ... here.
        * mf-hooks3.c (struct pthread_info): Remove.
        (__mf_pthread_info, __mf_pthread_info_idx): Remove.
        (LIBMUDFLAPTH_THREADS_MAX): Set to 1021.
        (struct mf_thread_data): New.
        (mf_thread_data, mf_thread_data_lock): New.
        (__mf_allocate_blank_threadinfo): Remove.
        (__mf_find_threadinfo): Rewrite and simplify.  Only use if TLS is
        not available.
        (__mf_state_perthread): Remove.
        (__mf_get_state, __mf_set_state): New.
        (__mf_pthread_cleanup): Use &errno, rather than saved pointer.
        Update mf_thread_data killing procedure.
        (__mf_pthread_spawner): Similarly.
        (__mf_0fn_pthread_create): Only use wrapper if necessary.  Remove
        code to allocate thread stack space.
        (__mf_0fn_pthread_join, pthread_join): Remove.
        (__mf_0fn_pthread_exit, pthread_exit): Remove.
        * mf-impl.h (dyn_pthread_join, dyn_pthread_exit): Remove.
        (__mf_state_1): Rename from __mf_state; use TLS when available.
        (__mf_get_state, __mf_set_state): New.  Update all users.
        * mf-runtime.c (begin_recursion_protect1): New.
        (BEGIN_RECURSION_PROTECT): Use it.
        (__mf_state_1): Rename from __mf_state; use TLS when available.
        (threads_active_p): Remove.
        (__mf_usage): Compute it directly.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102108 138bc75d-0d04-0410-961f-82ee72b054a4

14 files changed:
gcc/ChangeLog
gcc/gcc.c
libmudflap/ChangeLog
libmudflap/Makefile.in
libmudflap/acinclude.m4 [new file with mode: 0644]
libmudflap/aclocal.m4
libmudflap/config.h.in
libmudflap/configure
libmudflap/configure.ac
libmudflap/mf-hooks1.c
libmudflap/mf-hooks3.c
libmudflap/mf-impl.h
libmudflap/mf-runtime.c
libmudflap/testsuite/Makefile.in

index b5e551c..2f8eeba 100644 (file)
@@ -1,3 +1,7 @@
+2005-07-16  Richard Henderson  <rth@redhat.com>
+
+       * gcc.c (MFWRAP_SPEC): Don't wrap pthread_join or pthread_exit.
+
 2005-07-16 Danny Berlin <dberlin@dberlin.org>
           Kenneth Zadeck <zadeck@naturalbridge.com>
 
index 5317516..a701d2c 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -598,7 +598,7 @@ proper position among the other output files.  */
 #define MFWRAP_SPEC " %{static: %{fmudflap|fmudflapth: \
  --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc\
  --wrap=mmap --wrap=munmap --wrap=alloca\
-} %{fmudflapth: --wrap=pthread_create --wrap=pthread_join --wrap=pthread_exit\
+} %{fmudflapth: --wrap=pthread_create\
 }} %{fmudflap|fmudflapth: --wrap=main}"
 #endif
 #ifndef MFLIB_SPEC
index 8e39393..f9f1380 100644 (file)
@@ -1,3 +1,36 @@
+2005-07-16  Richard Henderson  <rth@redhat.com>
+
+       * acinclude.m4: New file.
+       * configure.ac: Invoke LIBMUDFLAP_CHECK_TLS.
+       * configure, config.h.in, Makefile.in, testsuite/Makefile.in: Rebuild.
+       * mf-hooks1.c (__mf_0fn_malloc): Move body from ...
+       (__mf_0fn_calloc): ... here.
+       * mf-hooks3.c (struct pthread_info): Remove.
+       (__mf_pthread_info, __mf_pthread_info_idx): Remove.
+       (LIBMUDFLAPTH_THREADS_MAX): Set to 1021.
+       (struct mf_thread_data): New.
+       (mf_thread_data, mf_thread_data_lock): New.
+       (__mf_allocate_blank_threadinfo): Remove.
+       (__mf_find_threadinfo): Rewrite and simplify.  Only use if TLS is
+       not available.
+       (__mf_state_perthread): Remove.
+       (__mf_get_state, __mf_set_state): New.
+       (__mf_pthread_cleanup): Use &errno, rather than saved pointer.
+       Update mf_thread_data killing procedure.
+       (__mf_pthread_spawner): Similarly.
+       (__mf_0fn_pthread_create): Only use wrapper if necessary.  Remove
+       code to allocate thread stack space.
+       (__mf_0fn_pthread_join, pthread_join): Remove.
+       (__mf_0fn_pthread_exit, pthread_exit): Remove.
+       * mf-impl.h (dyn_pthread_join, dyn_pthread_exit): Remove.
+       (__mf_state_1): Rename from __mf_state; use TLS when available.
+       (__mf_get_state, __mf_set_state): New.  Update all users.
+       * mf-runtime.c (begin_recursion_protect1): New.
+       (BEGIN_RECURSION_PROTECT): Use it.
+       (__mf_state_1): Rename from __mf_state; use TLS when available.
+       (threads_active_p): Remove.
+       (__mf_usage): Compute it directly.
+
 2005-06-19  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * testsuite/libmudflap.c/externs-1.c (main): Add return statement.
index dfd433a..24fa221 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.9.3 from Makefile.am.
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004  Free Software Foundation, Inc.
+# 2003, 2004, 2005  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.
@@ -49,8 +49,9 @@ DIST_COMMON = $(am__configure_deps) $(include_HEADERS) \
        $(top_srcdir)/configure ChangeLog
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
-       $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
+       $(top_srcdir)/../config/lead-dot.m4 $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/../libtool.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 \
@@ -463,7 +464,13 @@ uninstall-includeHEADERS:
 #     (which will cause the Makefiles to be regenerated when you run `make');
 # (2) otherwise, pass the desired values on the `make' command line.
 $(RECURSIVE_TARGETS):
-       @set fnord $$MAKEFLAGS; amf=$$2; \
+       @failcom='exit 1'; \
+       for f in x $$MAKEFLAGS; do \
+         case $$f in \
+           *=* | --[!k]*);; \
+           *k*) failcom='fail=yes';; \
+         esac; \
+       done; \
        dot_seen=no; \
        target=`echo $@ | sed s/-recursive//`; \
        list='$(SUBDIRS)'; for subdir in $$list; do \
@@ -475,7 +482,7 @@ $(RECURSIVE_TARGETS):
            local_target="$$target"; \
          fi; \
          (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
-          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+         || eval $$failcom; \
        done; \
        if test "$$dot_seen" = "no"; then \
          $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
@@ -483,7 +490,13 @@ $(RECURSIVE_TARGETS):
 
 mostlyclean-recursive clean-recursive distclean-recursive \
 maintainer-clean-recursive:
-       @set fnord $$MAKEFLAGS; amf=$$2; \
+       @failcom='exit 1'; \
+       for f in x $$MAKEFLAGS; do \
+         case $$f in \
+           *=* | --[!k]*);; \
+           *k*) failcom='fail=yes';; \
+         esac; \
+       done; \
        dot_seen=no; \
        case "$@" in \
          distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
@@ -504,7 +517,7 @@ maintainer-clean-recursive:
            local_target="$$target"; \
          fi; \
          (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
-          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+         || eval $$failcom; \
        done && test -z "$$fail"
 tags-recursive:
        list='$(SUBDIRS)'; for subdir in $$list; do \
@@ -579,7 +592,7 @@ distclean-tags:
 distdir: $(DISTFILES)
        $(am__remove_distdir)
        mkdir $(distdir)
-       $(mkdir_p) $(distdir)/.. $(distdir)/testsuite
+       $(mkdir_p) $(distdir)/.. $(distdir)/../config $(distdir)/testsuite
        @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
        list='$(DISTFILES)'; for file in $$list; do \
diff --git a/libmudflap/acinclude.m4 b/libmudflap/acinclude.m4
new file mode 100644 (file)
index 0000000..4308f50
--- /dev/null
@@ -0,0 +1,72 @@
+dnl Check whether the target supports TLS.
+AC_DEFUN([LIBMUDFLAP_CHECK_TLS], [
+  LIBMUDFLAP_ENABLE(tls, yes, [Use thread-local storage])
+  AC_CACHE_CHECK([whether the target supports thread-local storage],
+                have_tls, [
+    AC_RUN_IFELSE([__thread int a; int b; int main() { return a = b; }],
+      [dnl If the test case passed with dynamic linking, try again with
+      dnl static linking.  This fails at least with some older Red Hat
+      dnl releases.
+      save_LDFLAGS="$LDFLAGS"
+      LDFLAGS="-static $LDFLAGS"
+      AC_RUN_IFELSE([__thread int a; int b; int main() { return a = b; }],
+                   [have_tls=yes], [have_tls=no], [])
+      LDFLAGS="$save_LDFLAGS"],
+      [have_tls=no],
+      [AC_COMPILE_IFELSE([__thread int foo;], [have_tls=yes], [have_tls=no])]
+    )])
+  if test "$enable_tls $have_tls" = "yes yes"; then
+    AC_DEFINE(HAVE_TLS, 1,
+             [Define to 1 if the target supports thread-local storage.])
+  fi])
+
+dnl ----------------------------------------------------------------------
+dnl This whole bit snagged from libgfortran.
+
+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 LIBMUDFLAP_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([LIBMUDFLAP_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
+])
index 99613bf..95667ef 100644 (file)
@@ -1,7 +1,7 @@
-# generated automatically by aclocal 1.9.3 -*- Autoconf -*-
+# generated automatically by aclocal 1.9.5 -*- Autoconf -*-
 
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-# Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 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.
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
-#                                                        -*- Autoconf -*-
-# Copyright (C) 2002, 2003  Free Software Foundation, Inc.
-# Generated from amversion.in; do not edit by hand.
-
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# Copyright (C) 2002, 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_AUTOMAKE_VERSION(VERSION)
 # ----------------------------
@@ -40,26 +28,15 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
 # Call AM_AUTOMAKE_VERSION so it can be traced.
 # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-        [AM_AUTOMAKE_VERSION([1.9.3])])
-
-# AM_AUX_DIR_EXPAND
-
-# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+        [AM_AUTOMAKE_VERSION([1.9.5])])
 
-# This program 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, or (at your option)
-# any later version.
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# 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
@@ -106,26 +83,16 @@ AC_PREREQ([2.50])dnl
 am_aux_dir=`cd $ac_aux_dir && pwd`
 ])
 
-# AM_CONDITIONAL                                              -*- Autoconf -*-
-
-# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
-
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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.
+# AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# Copyright (C) 1997, 2000, 2001, 2003, 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 6
+# serial 7
 
 # AM_CONDITIONAL(NAME, SHELL-CONDITION)
 # -------------------------------------
@@ -149,26 +116,15 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# serial 7                                             -*- Autoconf -*-
 
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 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.
 
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
+# serial 8
 
 # 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,
@@ -177,7 +133,6 @@ fi])])
 # CC etc. in the Makefile, will ask for an AC_PROG_CC use...
 
 
-
 # _AM_DEPENDENCIES(NAME)
 # ----------------------
 # See how the compiler implements dependency checking.
@@ -317,27 +272,16 @@ AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
 AC_SUBST([AMDEPBACKSLASH])
 ])
 
-# Generate code to set up dependency tracking.   -*- Autoconf -*-
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
-#   Free Software Foundation, Inc.
-
-# This program 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, or (at your option)
-# any later version.
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 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
+#serial 3
 
 # _AM_OUTPUT_DEPENDENCY_COMMANDS
 # ------------------------------
@@ -396,30 +340,19 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
      [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
 ])
 
-# Do all the work for Automake.                            -*- Autoconf -*-
-
-# 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.
+# Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 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.
 
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# serial 12
 
-# serial 11
+# 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])
@@ -521,87 +454,31 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
 
+# 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_SH
 # ------------------
 # Define $install_sh.
-
-# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
 AC_DEFUN([AM_PROG_INSTALL_SH],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
 install_sh=${install_sh-"$am_aux_dir/install-sh"}
 AC_SUBST(install_sh)])
 
-#                                                          -*- Autoconf -*-
-# Copyright (C) 2003  Free Software Foundation, Inc.
-
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 1
-
-# Check whether the underlying file-system supports filenames
-# with a leading dot.  For instance MS-DOS doesn't.
-AC_DEFUN([AM_SET_LEADING_DOT],
-[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
-AC_SUBST([am__leading_dot])])
-
-# Add --enable-maintainer-mode option to configure.
+# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
 # From Jim Meyering
 
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 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.
 
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 3
+# serial 4
 
 AC_DEFUN([AM_MAINTAINER_MODE],
 [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
@@ -620,26 +497,15 @@ AC_DEFUN([AM_MAINTAINER_MODE],
 
 AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
 
-# Check to see how 'make' treats includes.     -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
-
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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.
+# Check to see how 'make' treats includes.                 -*- Autoconf -*-
 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# Copyright (C) 2001, 2002, 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.
 
-# serial 2
+# serial 3
 
 # AM_MAKE_INCLUDE()
 # -----------------
@@ -683,27 +549,16 @@ AC_MSG_RESULT([$_am_result])
 rm -f confinc confmf
 ])
 
-#  -*- Autoconf -*-
-
-
-# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# Copyright (C) 1997, 1999, 2000, 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.
 
-# serial 3
+# serial 4
 
 # AM_MISSING_PROG(NAME, PROGRAM)
 # ------------------------------
@@ -729,27 +584,16 @@ else
 fi
 ])
 
+# Copyright (C) 2003, 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.
+
 # AM_PROG_MKDIR_P
 # ---------------
 # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
-
-# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
-
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
+#
 # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
 # created by `make install' are always world readable, even if the
 # installer happens to have an overly restrictive umask (e.g. 077).
@@ -803,25 +647,14 @@ else
 fi
 AC_SUBST([mkdir_p])])
 
-# Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004
+# Copyright (C) 1998, 1999, 2000, 2001, 2003, 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.
 
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 4
+# serial 5
 
 # AM_ENABLE_MULTILIB([MAKEFILE], [REL-TO-TOP-SRCDIR])
 # ---------------------------------------------------
@@ -872,26 +705,15 @@ multi_basedir="$multi_basedir"
 CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
 CC="$CC"])])dnl
 
-# Helper functions for option handling.                    -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003  Free Software Foundation, Inc.
-
-# This program 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, or (at your option)
-# any later version.
+# Helper functions for option handling.                     -*- Autoconf -*-
 
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# Copyright (C) 2001, 2002, 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.
 
-# serial 2
+# serial 3
 
 # _AM_MANGLE_OPTION(NAME)
 # -----------------------
@@ -916,28 +738,16 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-#
-# Check to make sure that the build environment is sane.
-#
-
-# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# Copyright (C) 1996, 1997, 2000, 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.
 
-# serial 3
+# serial 4
 
 # AM_SANITY_CHECK
 # ---------------
@@ -980,25 +790,14 @@ Check your system clock])
 fi
 AC_MSG_RESULT(yes)])
 
-# AM_PROG_INSTALL_STRIP
-
-# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# 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
@@ -1021,25 +820,13 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004  Free Software Foundation, Inc.
-
-# This program 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, or (at your option)
-# any later version.
-
-# This program 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 this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 1
+# 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)
 # --------------------
@@ -1127,4 +914,6 @@ AC_SUBST([am__tar])
 AC_SUBST([am__untar])
 ]) # _AM_PROG_TAR
 
-m4_include([../libtool.m4])
+m4_include([../config/depstand.m4])
+m4_include([../config/lead-dot.m4])
+m4_include([acinclude.m4])
index 7685b57..b14e2e9 100644 (file)
 /* Define to 1 if you have the <sys/wait.h> header file. */
 #undef HAVE_SYS_WAIT_H
 
+/* Define to 1 if the target supports thread-local storage. */
+#undef HAVE_TLS
+
 /* union semun defined in sys/ipc.h or sys/sem.h */
 #undef HAVE_UNION_SEMUN
 
index ab7d227..03b3be5 100755 (executable)
@@ -850,6 +850,8 @@ Optional Features:
   --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)
+  _g_switchUse thread-local storage
+                          [default=yes]
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -5831,7 +5833,7 @@ test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
 case $host in
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 5834 "configure"' > conftest.$ac_ext
+  echo '#line 5836 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -6898,6 +6900,135 @@ else
   multilib_arg=
 fi
 
+# See if we support thread-local storage.
+
+   # Check whether --enable-tls or --disable-tls was given.
+if test "${enable_tls+set}" = set; then
+  enableval="$enable_tls"
+
+      case "$enableval" in
+       yes|no) ;;
+       *) { { echo "$as_me:$LINENO: error: Argument to enable/disable tls must be yes or no" >&5
+echo "$as_me: error: Argument to enable/disable tls must be yes or no" >&2;}
+   { (exit 1); exit 1; }; } ;;
+      esac
+
+else
+  enable_tls=yes
+fi;
+
+  echo "$as_me:$LINENO: checking whether the target supports thread-local storage" >&5
+echo $ECHO_N "checking whether the target supports thread-local storage... $ECHO_C" >&6
+if test "${have_tls+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    if test "$cross_compiling" = yes; then
+  cat >conftest.$ac_ext <<_ACEOF
+__thread int foo;
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_tls=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+have_tls=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+else
+  cat >conftest.$ac_ext <<_ACEOF
+__thread int a; int b; int main() { return a = b; }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+                    save_LDFLAGS="$LDFLAGS"
+      LDFLAGS="-static $LDFLAGS"
+      if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+__thread int a; int b; int main() { return a = b; }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_tls=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+have_tls=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+      LDFLAGS="$save_LDFLAGS"
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+have_tls=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $have_tls" >&5
+echo "${ECHO_T}$have_tls" >&6
+  if test "$enable_tls $have_tls" = "yes yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS 1
+_ACEOF
+
+  fi
+
                               ac_config_files="$ac_config_files Makefile testsuite/Makefile testsuite/mfconfig.exp"
 
 cat >confcache <<\_ACEOF
index 60c2c7f..58a7c73 100644 (file)
@@ -229,5 +229,8 @@ else
   multilib_arg=
 fi
 
+# See if we support thread-local storage.
+LIBMUDFLAP_CHECK_TLS
+
 AC_CONFIG_FILES([Makefile testsuite/Makefile testsuite/mfconfig.exp])
 AC_OUTPUT
index 6f9d159..9460e44 100644 (file)
@@ -79,7 +79,19 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 void *
 __mf_0fn_malloc (size_t c)
 {
-  /* fprintf (stderr, "0fn malloc c=%lu\n", c); */
+  enum foo { BS = 4096, NB=10 };
+  static char bufs[NB][BS];
+  static unsigned bufs_used[NB];
+  unsigned i;
+
+  for (i=0; i<NB; i++)
+    {
+      if (! bufs_used[i] && c < BS)
+       {
+         bufs_used[i] = 1;
+         return & bufs[i][0];
+       }
+    }
   return NULL;
 }
 #endif
@@ -114,21 +126,7 @@ WRAPPER(void *, malloc, size_t c)
 void *
 __mf_0fn_calloc (size_t c, size_t n)
 {
-  enum foo { BS = 4096, NB=10 };
-  static char bufs[NB][BS];
-  static unsigned bufs_used[NB];
-  unsigned i;
-
-  /* fprintf (stderr, "0fn calloc c=%lu n=%lu\n", c, n); */
-  for (i=0; i<NB; i++)
-    {
-      if (! bufs_used[i] && (c*n) < BS)
-       {
-         bufs_used[i] = 1;
-         return & bufs[i][0];
-       }
-    }
-  return NULL;
+  return __mf_0fn_malloc (c * n);
 }
 #endif
 
@@ -194,7 +192,7 @@ WRAPPER(void *, realloc, void *buf, size_t c)
   /* Ensure heap wiping doesn't occur during this peculiar
      unregister/reregister pair.  */
   LOCKTH ();
-  __mf_state = reentrant;
+  __mf_set_state (reentrant);
   saved_wipe_heap = __mf_opts.wipe_heap;
   __mf_opts.wipe_heap = 0;
 
@@ -212,7 +210,7 @@ WRAPPER(void *, realloc, void *buf, size_t c)
   /* Restore previous setting.  */
   __mf_opts.wipe_heap = saved_wipe_heap;
 
-  __mf_state = active;
+  __mf_set_state (active);
   UNLOCKTH ();
 
   return result;
index f980c9b..f3006b2 100644 (file)
@@ -1,5 +1,5 @@
 /* Mudflap: narrow-pointer bounds-checking by tree rewriting.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Frank Ch. Eigler <fche@redhat.com>
    and Graydon Hoare <graydon@redhat.com>
 
@@ -52,14 +52,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <sys/types.h>
-#include <sys/mman.h>
 #include <unistd.h>
 #include <assert.h>
 #include <errno.h>
-#include <limits.h>
-#include <sched.h>
-#include <fcntl.h>
+#include <stdbool.h>
 
 #include "mf-runtime.h"
 #include "mf-impl.h"
@@ -68,276 +64,214 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #error "Do not compile this file with -fmudflap!"
 #endif
 
-
-/* Multithreading support hooks.  */
-
-
-
 #ifndef LIBMUDFLAPTH
 #error "pthreadstuff is to be included only in libmudflapth"
 #endif
 
+/* ??? Why isn't this done once in the header files.  */
+DECLARE(void *, malloc, size_t sz);
+DECLARE(void, free, void *ptr);
+DECLARE(int, pthread_create, pthread_t *thr, const pthread_attr_t *attr,
+       void * (*start) (void *), void *arg);
 
 
-/* Describe a thread (dead or alive). */
-struct pthread_info
-{
-  short used_p;  /* Is this slot in use?  */
-  short dead_p;  /* Is this thread dead?  */
-  pthread_t self; /* The thread id.  */
-
-  /* If libmudflapth allocated the stack, store its adjusted base/size.  */
-  void *stack;
-  size_t stack_size;
-  /* The _alloc fields store unadjusted values from the moment of allocation.  */
-  void *stack_alloc;
-  size_t stack_size_alloc;
-
-  int *thread_errno;
-  enum __mf_state_enum state;
-};
+/* Multithreading support hooks.  */
 
 
-/* Describe the startup information for a new user thread.  */
-struct pthread_start_info
-{
-  /* The user's thread entry point and argument.  */
-  void * (*user_fn)(void *);
-  void *user_arg;
-
-  /* Set by user thread when this startup struct may be disposed of.  */
-  struct pthread_info *thread_info;
-};
+#ifndef HAVE_TLS
+/* We don't have TLS.  Ordinarily we could use pthread keys, but since we're
+   commandeering malloc/free that presents a few problems.  The first is that
+   we'll recurse from __mf_get_state to pthread_setspecific to malloc back to
+   __mf_get_state during thread startup.  This can be solved with clever uses
+   of a mutex.  The second problem is that thread shutdown is indistinguishable
+   from thread startup, since libpthread is deallocating our state variable.
+   I've no good solution for this.
 
+   Which leaves us to handle this mess by totally by hand.  */
 
+/* Yes, we want this prime.  If pthread_t is a pointer, it's almost always
+   page aligned, and if we use a smaller power of 2, this results in "%N"
+   being the worst possible hash -- all threads hash to zero.  */
+#define LIBMUDFLAPTH_THREADS_MAX 1021
 
+struct mf_thread_data
+{
+  pthread_t self;
+  unsigned char used_p;
+  unsigned char state;
+};
 
-/* To avoid dynamic memory allocation, use static array to store these
-   thread description structs.  The second (_idx) array is used as a
-   simple caching hash table, mapping PTHREAD_HASH(thread) to its
-   index in __mf_pthread_info[]. */
+static struct mf_thread_data mf_thread_data[LIBMUDFLAPTH_THREADS_MAX];
+static pthread_mutex_t mf_thread_data_lock = PTHREAD_MUTEX_INITIALIZER;
 
-#define LIBMUDFLAPTH_THREADS_MAX 1024
-static struct pthread_info __mf_pthread_info[LIBMUDFLAPTH_THREADS_MAX];
-static unsigned __mf_pthread_info_idx[LIBMUDFLAPTH_THREADS_MAX];
-#define PTHREAD_HASH(p) ((unsigned) (p) % LIBMUDFLAPTH_THREADS_MAX)
+/* Try to identify the main thread when filling in mf_thread_data.  We
+   should always be called at least once from the main thread before 
+   any new threads are spawned.  */
+static int main_seen_p;
 
+#define PTHREAD_HASH(p) ((unsigned long) (p) % LIBMUDFLAPTH_THREADS_MAX)
 
-/* Find any old empty entry in __mf_pthread_info; mark it used and
-   return it.  Return NULL if there are no more available slots.  */
-struct pthread_info*
-__mf_allocate_blank_threadinfo (unsigned* idx)
+static struct mf_thread_data *
+__mf_find_threadinfo (int alloc)
 {
-  static unsigned probe = LIBMUDFLAPTH_THREADS_MAX-1;
-  unsigned probe_at_start = probe;
-  static pthread_mutex_t mutex =
-#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
-    PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-#else
-    PTHREAD_MUTEX_INITIALIZER;
+  pthread_t self = pthread_self ();
+  unsigned long hash = PTHREAD_HASH (self);
+  unsigned long rehash;
+
+#ifdef __alpha__
+  /* Alpha has the loosest memory ordering rules of all.  We need a memory
+     barrier to flush the reorder buffer before considering a *read* of a
+     shared variable.  Since we're not always taking a lock, we have to do
+     this by hand.  */
+  __sync_synchronize ();
 #endif
-  int rc;
 
-  rc = pthread_mutex_lock (& mutex);
-  assert (rc == 0);
+  rehash = hash;
+  while (1)
+    {
+      if (mf_thread_data[rehash].used_p && mf_thread_data[rehash].self == self)
+       return &mf_thread_data[rehash];
+
+      rehash += 7;
+      if (rehash >= LIBMUDFLAPTH_THREADS_MAX)
+       rehash -= LIBMUDFLAPTH_THREADS_MAX;
+      if (rehash == hash)
+       break;
+    }
 
-  /* Look for a blank spot starting one past the last one we found. */
-  do
+  if (alloc)
     {
-      probe = (probe + 1) % LIBMUDFLAPTH_THREADS_MAX;
-      struct pthread_info* pi = & __mf_pthread_info [probe];
-      if (! pi->used_p)
+      pthread_mutex_lock (&mf_thread_data_lock);
+
+      rehash = hash;
+      while (1)
        {
-         /* memset (pi, 0, sizeof (*pi)); */
-         pi->used_p = 1;
-         if (idx != NULL) *idx = probe;
-         /* VERBOSE_TRACE ("allocated threadinfo slot %u\n", probe); */
-         rc = pthread_mutex_unlock (& mutex);
-         assert (rc == 0);
-         return pi;
+         if (!mf_thread_data[rehash].used_p)
+           {
+             mf_thread_data[rehash].self = self;
+             __sync_synchronize ();
+             mf_thread_data[rehash].used_p = 1;
+
+             pthread_mutex_unlock (&mf_thread_data_lock);
+             return &mf_thread_data[rehash];
+           }
+
+         rehash += 7;
+         if (rehash >= LIBMUDFLAPTH_THREADS_MAX)
+           rehash -= LIBMUDFLAPTH_THREADS_MAX;
+         if (rehash == hash)
+           break;
        }
+
+      pthread_mutex_unlock (&mf_thread_data_lock);
     }
-  while (probe != probe_at_start);
 
-  rc = pthread_mutex_unlock (& mutex);
-  assert (rc == 0);
   return NULL;
 }
 
-
-/* Find and return the pthread_info struct for the current thread.
-   There might already be one in __mf_pthread_info for this thread, in
-   which case return it.  There may not be one (if this is a main
-   thread, an auxiliary -lpthread manager, or an actual user thread
-   making an early call into libmudflap.  In these cases, create a new
-   entry.  If not it's not the main thread, put it into reentrant
-   initial state.
-
-   NB: VERBOSE_TRACE type functions are not generally safe to call
-   from this context, since a new thread might just be "booting up",
-   making printf unsafe to call.
-*/
-static struct pthread_info*
-__mf_find_threadinfo ()
+enum __mf_state_enum
+__mf_get_state (void)
 {
-  pthread_t it = pthread_self ();
-  unsigned *hash = & __mf_pthread_info_idx [PTHREAD_HASH (it)];
-  struct pthread_info *result = NULL;
-  static pthread_t last;
-  static int main_thread_seen_p;
-
-  /* Check out the lookup cache; failing that, do a linear search
-     around the table.  */
-  {
-    struct pthread_info* pi = & __mf_pthread_info [*hash];
-    unsigned i;
-
-    if (pi->used_p && pi->self == it)
-      result = pi;
-    else for (i = 0; i < LIBMUDFLAPTH_THREADS_MAX; i++)
-      {
-       struct pthread_info* pi2 = & __mf_pthread_info [i];
-       if (pi2->used_p && pi2->self == it)
-         {
-           *hash = i;
-           result = pi2;
-           break;
-         }
-      }
-  }
-
-  if (result == NULL)
-    {
-      /* Create a __mf_pthread_info record for the main thread.  It's
-        different from the auto-recognized worker bees because for
-        example we can assume that it's a fully stack/errno-equipped
-        thread. */
-
-      /* This must be the main thread, until now unseen in libmudflap.  */
-      unsigned *hash = & __mf_pthread_info_idx [PTHREAD_HASH (it)];
-      struct pthread_info* pi = __mf_allocate_blank_threadinfo (hash);
-      assert (pi != NULL);
-      assert (pi->used_p);
-      result = pi;
-      result->self = it;
-
-      if (! main_thread_seen_p)
-       {
-         result->state = active;
-         /* NB: leave result->thread_errno unset, as main thread's errno
-            has already been registered in __mf_init.  */
-         /* NB: leave stack-related fields unset, to avoid
-            deallocation.  */
-         main_thread_seen_p = 1;
-         /* VERBOSE_TRACE ("identified self as main thread\n"); */
-       }
-      else
-       {
-         result->state = reentrant;
-         /* NB: leave result->thread_errno unset, as worker thread's
-            errno is unlikely to be used, and user threads fill them
-            in during __mf_pthread_spawn().  */
-         /* NB: leave stack-related fields unset, leaving pthread_create
-            to fill them in for user threads, leaving them empty for
-            other threads.  */
-         /* VERBOSE_TRACE ("identified self as new aux or user thread\n"); */
-       }
-    }
-
-  if (last != it)
+  struct mf_thread_data *data = __mf_find_threadinfo (0);
+  if (data)
+    return data->state;
+
+  /* The main thread needs to default to active state, so that the global
+     constructors are processed in the active state.  Child threads should
+     be considered to be in the reentrant state, so that we don't wind up
+     doing Screwy Things inside the thread library; it'll get reset to 
+     active state in __mf_pthread_spawner before user code is invoked.
+
+     The trickiest bit here is that the LinuxThreads pthread_manager thread
+     should *always* be considered to be reentrant, so that none of our 
+     hooks actually do anything.  Why?  Because that thread isn't a real
+     thread from the point of view of the thread library, and so lots of
+     stuff isn't initialized, leading to SEGV very quickly.  Even calling
+     pthread_self is a bit suspect, but it happens to work.  */
+
+  if (main_seen_p)
+    return reentrant;
+  else
     {
-      /*
-      VERBOSE_TRACE ("found threadinfo for %u, slot %u\n",
-                    (unsigned) it,
-                    (unsigned) *hash);
-      */
-      last = it;
+      main_seen_p = 1;
+      data = __mf_find_threadinfo (1);
+      data->state = active;
+      return active;
     }
+}
 
-  assert (result != NULL);
-  assert (result->self == it);
-
-  return result;
+void
+__mf_set_state (enum __mf_state_enum new_state)
+{
+  struct mf_thread_data *data = __mf_find_threadinfo (1);
+  data->state = new_state;
 }
+#endif
 
+/* The following two functions are used only with __mf_opts.heur_std_data.
+   We're interested in recording the location of the thread-local errno
+   variable.
 
+   Note that this doesn't handle TLS references in general; we have no
+   visibility into __tls_get_data for when that memory is allocated at
+   runtime.  Hopefully we get to see the malloc or mmap operation that
+   eventually allocates the backing store.  */
 
-/* Return a pointer to the per-thread __mf_state variable.  */
-enum __mf_state_enum *
-__mf_state_perthread ()
+/* Describe the startup information for a new user thread.  */
+struct mf_thread_start_info
 {
-  assert (! __mf_starting_p);
-  return & (__mf_find_threadinfo()->state);
-}
+  /* The user's thread entry point and argument.  */
+  void * (*user_fn)(void *);
+  void *user_arg;
+};
 
 
 static void
 __mf_pthread_cleanup (void *arg)
 {
-  struct pthread_info *pi = arg;
-
-  /* XXX: This unregistration is not safe on platforms where distinct
-     threads share errno (or at least its virtual address).  */
-  if (pi->thread_errno != NULL)
-    __mf_unregister (pi->thread_errno, sizeof (int), __MF_TYPE_GUESS);
-
-  /* XXX: Only detached threads should designate themselves as dead
-     here.  Non-detached threads are marked dead after their
-     personalized pthread_join() call.  */
-  pi->state = reentrant;
-  pi->dead_p = 1;
+  if (__mf_opts.heur_std_data)
+    __mf_unregister (&errno, sizeof (errno), __MF_TYPE_GUESS);
 
-  VERBOSE_TRACE ("thread pi %p exiting\n", pi);
+#ifndef HAVE_TLS
+  struct mf_thread_data *data = __mf_find_threadinfo (0);
+  if (data)
+    data->used_p = 0;
+#endif
 }
 
 
 static void *
 __mf_pthread_spawner (void *arg)
 {
-  struct pthread_info *pi = __mf_find_threadinfo ();
   void *result = NULL;
 
-  /* Turn off reentrancy indications.  */
-  assert (pi->state == reentrant);
-  pi->state = active;
-
-  VERBOSE_TRACE ("new user thread\n");
+#ifndef HAVE_TLS
+  __mf_set_state (active);
+#endif
 
+  /* NB: We could use __MF_TYPE_STATIC here, but we guess that the thread
+     errno is coming out of some dynamically allocated pool that we already
+     know of as __MF_TYPE_HEAP. */
   if (__mf_opts.heur_std_data)
-    {
-      pi->thread_errno = & errno;
-      __mf_register (pi->thread_errno, sizeof (int),
-                    __MF_TYPE_GUESS, "errno area (thread)");
-      /* NB: we could use __MF_TYPE_STATIC above, but we guess that
-        the thread errno is coming out of some dynamically allocated
-        pool that we already know of as __MF_TYPE_HEAP. */
-    }
+    __mf_register (&errno, sizeof (errno), __MF_TYPE_GUESS,
+                  "errno area (thread)");
 
   /* We considered using pthread_key_t objects instead of these
      cleanup stacks, but they were less cooperative with the
      interposed malloc hooks in libmudflap.  */
-  pthread_cleanup_push (& __mf_pthread_cleanup, pi);
-
-  /* Call user thread */
-  {
-    /* Extract given entry point and argument.  */
-    struct pthread_start_info *psi = arg;
-    void * (*user_fn)(void *) = psi->user_fn;
-    void *user_arg = psi->user_arg;
+  /* ??? The pthread_key_t problem is solved above...  */
+  pthread_cleanup_push (__mf_pthread_cleanup, NULL);
 
-    /* Signal the main thread to resume.  */
-    psi->thread_info = pi;
+  /* Extract given entry point and argument.  */
+  struct mf_thread_start_info *psi = arg;
+  void * (*user_fn)(void *) = psi->user_fn;
+  void *user_arg = psi->user_arg;
+  CALL_REAL (free, arg);
 
-    result = (*user_fn)(user_arg);
-  }
+  result = (*user_fn)(user_arg);
 
   pthread_cleanup_pop (1 /* execute */);
 
-  /* NB: there is a slight race here.  The pthread_info field will now
-     say this thread is dead, but it may still be running .. right
-     here.  We try to check for this possibility using the
-     pthread_kill test below. */
-
   return result;
 }
 
@@ -357,245 +291,31 @@ __mf_0fn_pthread_create (pthread_t *thr, const pthread_attr_t *attr,
 WRAPPER(int, pthread_create, pthread_t *thr, const pthread_attr_t *attr,
         void * (*start) (void *), void *arg)
 {
-  DECLARE(int, munmap, void *p, size_t l);
-  DECLARE(void *, mmap, void *p, size_t l, int prot, int flags, int fd, off_t of);
-  DECLARE(int, pthread_create, pthread_t *thr, const pthread_attr_t *attr,
-         void * (*start) (void *), void *arg);
-  int result;
-  pthread_attr_t override_attr;
-  void *override_stack;
-  size_t override_stacksize;
-  void *override_stack_alloc = (void *) 0;
-  size_t override_stacksize_alloc = 0;
-  unsigned i;
+  int result, need_wrapper = 0;
 
   TRACE ("pthread_create\n");
 
-  /* Garbage-collect dead threads' stacks.  */
-  LOCKTH ();
-  for (i = 0; i < LIBMUDFLAPTH_THREADS_MAX; i++)
+#ifndef HAVE_TLS
+  need_wrapper = 1;
+#endif
+  need_wrapper |= __mf_opts.heur_std_data != 0;
+
+  if (need_wrapper)
     {
-      struct pthread_info *pi = & __mf_pthread_info [i];
-      if (! pi->used_p)
-       continue;
-      if (! pi->dead_p)
-       continue;
-
-      /* VERBOSE_TRACE ("thread %u pi %p stack cleanup deferred (%u)\n",
-        (unsigned) pi->self, pi, pi->dead_p); */
-
-      /* Delay actual deallocation by a few cycles, try to discourage the
-        race mentioned at the end of __mf_pthread_spawner().  */
-      if (pi->dead_p)
-       pi->dead_p ++;
-      if (pi->dead_p >= 10 /* XXX */)
-       {
-         if (pi->stack)
-           CALL_REAL (munmap, pi->stack_alloc, pi->stack_size_alloc);
+      struct mf_thread_start_info *si = CALL_REAL (malloc, sizeof (*si));
 
-         VERBOSE_TRACE ("slot %u freed, stack %p\n", i, pi->stack_alloc);
-         memset (pi, 0, sizeof (*pi));
+      /* Fill in startup-control fields.  */
+      si->user_fn = start;
+      si->user_arg = arg;
 
-         /* One round of garbage collection is enough.  */
-         break;
-       }
+      /* Actually create the thread.  */
+      result = CALL_REAL (pthread_create, thr, attr, __mf_pthread_spawner, si);
     }
-  UNLOCKTH ();
-
-  /* Let's allocate a stack for this thread, if one is not already
-     supplied by the caller.  We don't want to let e.g. the
-     linuxthreads manager thread do this allocation.  */
-  if (attr != NULL)
-    override_attr = *attr;
   else
-    pthread_attr_init (& override_attr);
-
-  /* Get supplied attributes, if any.  */
-  /* XXX: consider using POSIX2K attr_getstack() */
-  if (pthread_attr_getstackaddr (& override_attr, & override_stack) != 0 ||
-      pthread_attr_getstacksize (& override_attr, & override_stacksize) != 0)
     {
-      override_stack = NULL;
-      override_stacksize = 0;
+      /* If we're not handling heur_std_data, nothing special to do.  */
+      result = CALL_REAL (pthread_create, thr, attr, start, arg);
     }
 
-  /* Do we need to allocate the new thread's stack?  */
-  if (__mf_opts.thread_stack && override_stack == NULL)
-    {
-      uintptr_t alignment = 256; /* power of two */
-
-      /* Perturb the initial stack addresses slightly, to encourage
-        threads to have nonconflicting entries in the lookup cache
-        for their tracked stack objects.  */
-      static unsigned perturb = 0;
-      const unsigned perturb_delta = 32;
-      const unsigned perturb_count = 16;
-      perturb += perturb_delta;
-      if (perturb > perturb_delta*perturb_count) perturb = 0;
-
-      /* Use glibc x86 defaults */
-/* Should have been defined in <limits.h> */
-#ifndef PTHREAD_STACK_MIN
-#define PTHREAD_STACK_MIN 65536
-#endif
-      override_stacksize = max (PTHREAD_STACK_MIN, __mf_opts.thread_stack * 1024);
-
-
-#if defined(MAP_ANONYMOUS)
-#define MF_MAP_ANON MAP_ANONYMOUS
-#elif defined(MAP_ANON)
-#define MF_MAP_ANON MAP_ANON
-#endif
-
-#ifndef MAP_FAILED
-#define MAP_FAILED ((void *) -1)
-#endif
-
-#ifdef MF_MAP_ANON
-      override_stack = CALL_REAL (mmap, NULL, override_stacksize,
-                                 PROT_READ|PROT_WRITE,
-                                 MAP_PRIVATE|MF_MAP_ANON,
-                                 0, 0);
-#else
-      /* Try mapping /dev/zero instead.  */
-      {
-        static int zerofd = -1;
-        if (zerofd == -1)
-          zerofd = open ("/dev/zero", O_RDWR);
-        if (zerofd == -1)
-          override_stack = MAP_FAILED;
-        else
-          override_stack = CALL_REAL (mmap, NULL, override_stacksize,
-                                      PROT_READ|PROT_WRITE,
-                                      MAP_PRIVATE, zerofd, 0);
-      }
-#endif
-
-      if (override_stack == 0 || override_stack == MAP_FAILED)
-       {
-         errno = EAGAIN;
-         return -1;
-       }
-
-      VERBOSE_TRACE ("thread stack alloc %p size %lu\n",
-                    override_stack, (unsigned long) override_stacksize);
-
-      /* Save the original allocated values for later deallocation.  */
-      override_stack_alloc = override_stack;
-      override_stacksize_alloc = override_stacksize;
-
-      /* The stackaddr pthreads attribute is a candidate stack pointer.
-        It must point near the top or the bottom of this buffer, depending
-        on whether stack grows downward or upward, and suitably aligned.
-        On the x86, it grows down, so we set stackaddr near the top.  */
-      /* XXX: port logic */
-      override_stack = (void *)
-       (((uintptr_t) override_stack + override_stacksize - alignment - perturb)
-        & (~(uintptr_t)(alignment-1)));
-
-      /* XXX: consider using POSIX2K attr_setstack() */
-      if (pthread_attr_setstackaddr (& override_attr, override_stack) != 0 ||
-         pthread_attr_setstacksize (& override_attr,
-                                    override_stacksize - alignment - perturb) != 0)
-       {
-         /* This should not happen.  */
-         CALL_REAL (munmap, override_stack, override_stacksize);
-         errno = EAGAIN;
-         return -1;
-       }
-  }
-
-  /* Actually start the child thread.  */
-  {
-    struct pthread_start_info psi;
-    struct pthread_info *pi = NULL;
-
-    /* Fill in startup-control fields.  */
-    psi.user_fn = start;
-    psi.user_arg = arg;
-    psi.thread_info = NULL;
-
-    /* Actually create the thread.  */
-    __mf_state = reentrant;
-    result = CALL_REAL (pthread_create, thr, & override_attr,
-                       & __mf_pthread_spawner, (void *) & psi);
-    __mf_state = active;
-    /* We also hook pthread_join/pthread_exit to get into reentrant
-       mode during thread shutdown/cleanup.  */
-
-    /* Wait until child thread has progressed far enough into its
-       __mf_pthread_spawner() call.  */
-    while (1) /* XXX: timeout? */
-      {
-       volatile struct pthread_start_info *psip = & psi;
-       pi = psip->thread_info;
-       if (pi != NULL)
-         break;
-       sched_yield ();
-      }
-
-    /* Fill in remaining fields in pthread_info. */
-    pi->stack = override_stack;
-    pi->stack_size = override_stacksize;
-    pi->stack_alloc = override_stack_alloc;
-    pi->stack_size_alloc = override_stacksize_alloc;
-    /* XXX: this might be too late for future heuristics that attempt
-       to use thread stack bounds.  We may need to put the new thread
-       to sleep. */
-  }
-
-
-  /* May need to clean up if we created a pthread_attr_t of our own.  */
-  if (attr == NULL)
-    pthread_attr_destroy (& override_attr); /* NB: this shouldn't deallocate stack */
-
   return result;
 }
-
-
-
-#if PIC
-/* A special bootstrap variant. */
-int
-__mf_0fn_pthread_join (pthread_t thr, void **rc)
-{
-  return -1;
-}
-#endif
-
-
-#undef pthread_join
-WRAPPER(int, pthread_join, pthread_t thr, void **rc)
-{
-  DECLARE(int, pthread_join, pthread_t thr, void **rc);
-  int result;
-
-  TRACE ("pthread_join\n");
-  __mf_state = reentrant;
-  result = CALL_REAL (pthread_join, thr, rc);
-  __mf_state = active;
-
-  return result;
-}
-
-
-#if PIC
-/* A special bootstrap variant. */
-void
-__mf_0fn_pthread_exit (void *rc)
-{
-}
-#endif
-
-
-#undef pthread_exit
-WRAPPER(void, pthread_exit, void *rc)
-{
-  DECLARE(void, pthread_exit, void *rc);
-
-  TRACE ("pthread_exit\n");
-  /* __mf_state = reentrant; */
-  CALL_REAL (pthread_exit, rc);
-  /* NOTREACHED */
-  exit (0);  /* Satisfy noreturn attribute of pthread_exit.  */
-}
index 47abdf6..53c25b3 100644 (file)
@@ -207,9 +207,7 @@ enum __mf_dynamic_index
   dyn_munmap, dyn_realloc,
   dyn_INITRESOLVE,  /* Marker for last init-time resolution. */
 #ifdef LIBMUDFLAPTH
-  dyn_pthread_create,
-  dyn_pthread_join,
-  dyn_pthread_exit
+  dyn_pthread_create
 #endif
 };
 
@@ -233,12 +231,25 @@ extern pthread_mutex_t __mf_biglock;
 #define UNLOCKTH() do {} while (0)
 #endif
 
-#ifdef LIBMUDFLAPTH
-extern enum __mf_state_enum *__mf_state_perthread ();
-#define __mf_state (* __mf_state_perthread ())
+#if defined(LIBMUDFLAPTH) && !defined(HAVE_TLS)
+extern enum __mf_state_enum __mf_get_state (void);
+extern void __mf_set_state (enum __mf_state_enum);
 #else
-extern enum __mf_state_enum __mf_state;
+# ifdef LIBMUDFLAPTH
+extern __thread enum __mf_state_enum __mf_state_1;
+# else
+extern enum __mf_state_enum __mf_state_1;
+# endif
+static inline enum __mf_state_enum __mf_get_state (void)
+{
+  return __mf_state_1;
+}
+static inline void __mf_set_state (enum __mf_state_enum s)
+{
+  __mf_state_1 = s;
+}
 #endif
+
 extern int __mf_starting_p;
 extern struct __mf_options __mf_opts;
 
@@ -362,7 +373,7 @@ ret __mfwrap_ ## fname (__VA_ARGS__)
   {                                         \
     return CALL_BACKUP(fname, __VA_ARGS__); \
   }                                         \
-  else if (UNLIKELY (__mf_state == reentrant))   \
+  else if (UNLIKELY (__mf_get_state () == reentrant))   \
   {                                         \
     extern unsigned long __mf_reentrancy;   \
     __mf_reentrancy ++; \
index 317aeae..af584e7 100644 (file)
@@ -141,20 +141,25 @@ static void mfsplay_tree_rebalance (mfsplay_tree sp);
 #define __MF_VIOL_WATCH 5
 
 /* Protect against recursive calls. */
-#define BEGIN_RECURSION_PROTECT() do { \
-  if (UNLIKELY (__mf_state == reentrant)) { \
-    write (2, "mf: erroneous reentrancy detected in `", 38); \
-    write (2, __PRETTY_FUNCTION__, strlen(__PRETTY_FUNCTION__)); \
-    write (2, "'\n", 2); \
-    abort (); } \
-  __mf_state = reentrant;  \
-  } while (0)
 
-#define END_RECURSION_PROTECT() do { \
-  __mf_state = active; \
-  } while (0)
+static void
+begin_recursion_protect1 (const char *pf)
+{
+  if (__mf_get_state () == reentrant)
+    {
+      write (2, "mf: erroneous reentrancy detected in `", 38);
+      write (2, pf, strlen(pf));
+      write (2, "'\n", 2); \
+      abort ();
+    }
+  __mf_set_state (reentrant);
+}
 
+#define BEGIN_RECURSION_PROTECT() \
+  begin_recursion_protect1 (__PRETTY_FUNCTION__)
 
+#define END_RECURSION_PROTECT() \
+  __mf_set_state (active)
 
 /* ------------------------------------------------------------------------ */
 /* Required globals.  */
@@ -169,15 +174,16 @@ unsigned char __mf_lc_shift = LOOKUP_CACHE_SHIFT_DFL;
 #define LOOKUP_CACHE_SIZE (__mf_lc_mask + 1)
 
 struct __mf_options __mf_opts;
-
 int __mf_starting_p = 1;
-#ifndef LIBMUDFLAPTH
-enum __mf_state_enum __mf_state = active;
+
+#ifdef LIBMUDFLAPTH
+#ifdef HAVE_TLS
+__thread enum __mf_state_enum __mf_state_1 = active;
+#endif
 #else
-/* See __mf_state_perthread() in mf-hooks.c. */
+enum __mf_state_enum __mf_state_1 = active;
 #endif
 
-
 #ifdef LIBMUDFLAPTH
 pthread_mutex_t __mf_biglock =
 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
@@ -196,7 +202,6 @@ pthread_mutex_t __mf_biglock =
 #else
 #define pthread_join NULL
 #endif
-const void *threads_active_p = (void *) pthread_join;
 #endif
 
 
@@ -442,7 +447,7 @@ __mf_usage ()
            "any of the following options.  Use `-no-OPTION' to disable options.\n"
            "\n",
 #if HAVE_PTHREAD_H
-           (threads_active_p ? "multi-threaded " : "single-threaded "),
+           (pthread_join ? "multi-threaded " : "single-threaded "),
 #else
            "",
 #endif
@@ -2211,7 +2216,7 @@ __mf_sigusr1_respond ()
   if (__mf_sigusr1_received > __mf_sigusr1_handled)
     {
       __mf_sigusr1_handled ++;
-      assert (__mf_state == reentrant);
+      assert (__mf_get_state () == reentrant);
       __mfu_report ();
       handler_installed = 0; /* We may need to re-enable signal; this might be a SysV library. */
     }
index 69f0161..a3f386d 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.9.3 from Makefile.am.
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004  Free Software Foundation, Inc.
+# 2003, 2004, 2005  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.
@@ -40,8 +40,9 @@ subdir = testsuite
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
        $(srcdir)/mfconfig.exp.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
-       $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
+       $(top_srcdir)/../config/lead-dot.m4 $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/../libtool.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs