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]

[tree-ssa libmudflap] more threads changes


Hi -

The following patch cleans up some of the remaining reentrancy-prevention
code still in libmudflap.  This is code that prevents libmudflap from
falling into infinite recursion, should one of its hook functions be called
by the system at an inconvenient time.  Anyway, this code now plays better
with the pthread locking.  There is a baby pthreads test case too, and the
usual miscellanea.

By the way, for the last few days, the "pass-stratcliff" libmudflap test
has been failing at -O2/-O3.  With "-fdisable-tree-ssa" added, it passes.


2003-05-16  Frank Ch. Eigler  <fche@redhat.com>

	* gcc.c (cc1_options): Correct "-fmudflapth" handling.
	* tree-mudflap.c (mudflap_c_function, mf_build_check_statement_for):
	Use locally cached mask/shift values only in single-threaded mode.

2003-05-16  Frank Ch. Eigler  <fche@redhat.com>

	* Makefile.am (AM_CFLAGS): Remove "-ansi".
	* configure.in: Remove silly no-pthreads => no-shared logic.
	* Makefile.in, configure: Regenerated.
	* mf-heuristics.c (__mf_heuristic_check): Remove reentrancy hacks.
	* mf-hooks.c (BEGIN_PROTECT, END_PROTECT): Reorganize reentrancy
	code.  Count reentrancy events.
	(all hook functions): Don't directly manipulate __mf_state variable.
	Add TRACE calls to hook functions without them.
	* mf-impl.h (LOCKTH): Try to count lock contention events.
	(VERBOSE_TRACE, TRACE): Remove reentrancy hacks.
	* mf-runtime.c (BEGIN_RECURSION_PROTECT, END_RECURSION_PROTECT):
	Reorganize reentrancy code.
	(external __mf_ entry points): Use RECURSION_PROTECT mechanism to
	identify reentrancy with mutex holding times.
	(internal __mfu_ entry points): Remove internal reentrancy code.
	(__mf_init): Use ordinary locked calls.
	(__mfu_report): Print the two new counts.
	* testsuite/lib/libmudflap.exp:	Filter out junk ld/pthreads messages.
	* testsuite/libmudfap.cth/cthfrags.exp: New test driver.
	* testsuite/libmudflap.cth/pass37-frag.c: New pthreads test. 
	* testsuite/libmudfap.cth/cfrags.exp: Adapt to new libmudflap
	option defaults.



Index: gcc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcc.c,v
retrieving revision 1.324.2.30
diff -u -w -s -p -r1.324.2.30 gcc.c
--- gcc.c	13 May 2003 02:16:34 -0000	1.324.2.30
+++ gcc.c	16 May 2003 19:12:22 -0000
@@ -787,7 +787,7 @@ static const char *cc1_options =
  %{--target-help:--target-help}\
  %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\
  %{fsyntax-only:-o %j} %{-param*}\
- %{fmudflap|fmudflapth:-fmudflap -fno-builtin -fno-merge-constants}";
+ %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants}";
 
 static const char *asm_options =
 "%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
Index: tree-mudflap.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-mudflap.c,v
retrieving revision 1.1.2.40
diff -u -w -s -p -r1.1.2.40 tree-mudflap.c
--- tree-mudflap.c	7 May 2003 13:28:28 -0000	1.1.2.40
+++ tree-mudflap.c	16 May 2003 19:12:23 -0000
@@ -88,6 +88,8 @@ mudflap_c_function (t)
 
   mf_init_extern_trees ();
 
+  /* In multithreaded mode, don't cache the lookup cache parameters.  */
+  if (! (flag_mudflap > 1))
   mf_decl_cache_locals (& DECL_SAVED_TREE (t));
 
   mf_xform_decls (DECL_SAVED_TREE (t), DECL_ARGUMENTS (t));
@@ -104,6 +106,7 @@ mudflap_c_function (t)
       dump_function (TDI_mudflap, t);
     }
 
+  if (! (flag_mudflap > 1))
   mf_decl_clear_locals ();
 }
 
@@ -123,7 +126,7 @@ static GTY (()) tree mf_cache_array_decl
 static GTY (()) tree mf_cache_shift_decl;  /* extern const unsigned char __mf_lc_shift; */
 static GTY (()) tree mf_cache_mask_decl;   /* extern const uintptr_t __mf_lc_mask; */
 
-/* Their function-scope local shadows */
+/* Their function-scope local shadows, used in single-threaded mode only. */
 static GTY (()) tree mf_cache_shift_decl_l; /* auto const unsigned char __mf_lc_shift_l; */
 static GTY (()) tree mf_cache_mask_decl_l;  /* auto const uintptr_t __mf_lc_mask_l; */
 
@@ -570,9 +573,10 @@ mf_build_check_statement_for (ptrvalue, 
 
     t0 = build (RSHIFT_EXPR, mf_uintptr_type,
 		convert (mf_uintptr_type, t1_2a_1),
-		mf_cache_shift_decl_l);
+		(flag_mudflap > 1 ? mf_cache_shift_decl : mf_cache_shift_decl_l));
 
-    t1 = build (BIT_AND_EXPR, mf_uintptr_type, t0, mf_cache_mask_decl_l);
+    t1 = build (BIT_AND_EXPR, mf_uintptr_type, t0, 
+		(flag_mudflap > 1 ? mf_cache_mask_decl : mf_cache_mask_decl_l));
 
     t2 = mx_flag (build (ARRAY_REF,
 			 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (mf_cache_array_decl))),
@@ -593,7 +597,8 @@ mf_build_check_statement_for (ptrvalue, 
 			   0))
 	{
 	  __mf_check ();
-	  __mf_lookup_shift_1 = ...;
+          ... and only if single-threaded:
+	  __mf_lookup_shift_1 = f...;
 	  __mf_lookup_mask_l = ...;
 	}  */
   {
@@ -651,6 +656,8 @@ mf_build_check_statement_for (ptrvalue, 
 	              build_stmt (EXPR_STMT,
 				  build_function_call (mf_check_fndecl, t0)));
 
+    if (! (flag_mudflap > 1))
+      {
     t1_4_2 = chainon (t1_4_2,
 		      build_stmt (EXPR_STMT,
 				  build (MODIFY_EXPR,
@@ -664,6 +671,7 @@ mf_build_check_statement_for (ptrvalue, 
 					TREE_TYPE (mf_cache_mask_decl_l),
 					mf_cache_mask_decl_l,
 					mf_cache_mask_decl)));
+      }
 
     t0 = build_stmt (SCOPE_STMT, NULL_TREE);
     SCOPE_BEGIN_P (t0) = 1;


Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/Makefile.am,v
retrieving revision 1.1.2.28
diff -u -p -w -s -r1.1.2.28 Makefile.am
--- Makefile.am	12 May 2003 14:16:21 -0000	1.1.2.28
+++ Makefile.am	16 May 2003 19:09:34 -0000
@@ -8,7 +8,7 @@ AUTOMAKE_OPTIONS = 1.3 foreign
 MAINT_CHARSET = latin1
 SUBDIRS = testsuite
 
-AM_CFLAGS = -ansi -Wall
+AM_CFLAGS = -Wall
 
 if LIBMUDFLAPTH
 libmudflapth = libmudflapth.la
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/Makefile.in,v
retrieving revision 1.1.2.29
diff -u -p -w -s -r1.1.2.29 Makefile.in
--- Makefile.in	12 May 2003 14:16:21 -0000	1.1.2.29
+++ Makefile.in	16 May 2003 19:09:34 -0000
@@ -72,7 +72,6 @@ DLLTOOL = @DLLTOOL@
 EXEEXT = @EXEEXT@
 GCJ = @GCJ@
 GCJFLAGS = @GCJFLAGS@
-LDD = @LDD@
 LIBTOOL = @LIBTOOL@
 LN_S = @LN_S@
 MAINT = @MAINT@
@@ -94,7 +93,7 @@ AUTOMAKE_OPTIONS = 1.3 foreign
 MAINT_CHARSET = latin1
 SUBDIRS = testsuite
 
-AM_CFLAGS = -ansi -Wall
+AM_CFLAGS = -Wall
 @LIBMUDFLAPTH_TRUE@libmudflapth = @LIBMUDFLAPTH_TRUE@libmudflapth.la
 @LIBMUDFLAPTH_FALSE@libmudflapth = 
 
Index: configure.in
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/configure.in,v
retrieving revision 1.1.2.15
diff -u -p -w -s -r1.1.2.15 configure.in
--- configure.in	12 May 2003 14:16:21 -0000	1.1.2.15
+++ configure.in	16 May 2003 19:09:34 -0000
@@ -42,12 +42,6 @@ enable_shared=no])
 AC_CHECK_HEADERS(stdint.h execinfo.h signal.h pthread.h dlfcn.h)
 AC_CHECK_FUNCS(backtrace backtrace_symbols gettimeofday signal)
 
-# Disable shared libraries for hosts without pthread.h
-if test "x$ac_have_pthread_h" = ""; then
-   enable_shared=no
-fi
-
-
 AC_LIBTOOL_DLOPEN
 AM_PROG_LIBTOOL
 AC_SUBST(enable_shared)
Index: mf-heuristics.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-heuristics.c,v
retrieving revision 1.1.2.13
diff -u -p -w -s -r1.1.2.13 mf-heuristics.c
--- mf-heuristics.c	12 May 2003 14:16:21 -0000	1.1.2.13
+++ mf-heuristics.c	16 May 2003 19:09:34 -0000
@@ -139,12 +139,9 @@ __mf_heuristic_check (uintptr_t ptr, uin
 					 "%08lx-%08lx given %s",
 					 i, (uintptr_t) low, (uintptr_t) high, buf);
 			  
-			  /* XXX: bad hack; permit __mf_register to do its job.  */
-			  __mf_state = active;
 			  __mfu_register ((uintptr_t) low, (uintptr_t) (high-low),
 					  __MF_TYPE_GUESS, 
 					  "/proc/self/maps segment");
-			  __mf_state = reentrant;
 			  
 			  return 0; /* undecided (tending to cachable) */
 			} 
Index: mf-hooks.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-hooks.c,v
retrieving revision 1.1.2.32
diff -u -p -w -s -r1.1.2.32 mf-hooks.c
--- mf-hooks.c	12 May 2003 14:16:21 -0000	1.1.2.32
+++ mf-hooks.c	16 May 2003 19:09:34 -0000
@@ -47,9 +47,14 @@ XXX: libgcc license?
 
 #define BEGIN_PROTECT(ty, fname, ...)       \
   ty result;                                \
-  enum __mf_state old_state;                \
   if (UNLIKELY (__mf_state == reentrant))   \
   {                                         \
+    extern unsigned long __mf_reentrancy;   \
+    if (UNLIKELY (__mf_opts.verbose_trace)) { \
+      write (2, "mf: reentrancy detected in `", 28); \
+      write (2, __PRETTY_FUNCTION__, strlen(__PRETTY_FUNCTION__)); \
+      write (2, "'\n", 2); } \
+    __mf_reentrancy ++; \
     return CALL_REAL(fname, __VA_ARGS__);   \
   }                                         \
   else if (UNLIKELY (__mf_state == starting)) \
@@ -58,14 +63,11 @@ XXX: libgcc license?
   }                                         \
   else                                      \
   {                                         \
-     old_state = __mf_state;                \
-     __mf_state = reentrant;                \
      TRACE ("mf: %s\n", __PRETTY_FUNCTION__); \
   }
 
 #define END_PROTECT(ty, fname, ...)              \
   result = (ty) CALL_REAL(fname, __VA_ARGS__);   \
-  __mf_state = old_state;                        \
   return result;
 
 
@@ -94,8 +96,6 @@ WRAPPER(void *, malloc, size_t c)
 			__mf_opts.crumple_zone));
   result = (char *) CALL_REAL(malloc, size_with_crumple_zones);
   
-  __mf_state = old_state;
-  
   if (LIKELY(result))
     {
       result += __mf_opts.crumple_zone;
@@ -137,8 +137,6 @@ WRAPPER(void *, calloc, size_t c, size_t
   if (LIKELY(result))
     memset (result, 0, size_with_crumple_zones);
   
-  __mf_state = old_state;
-  
   if (LIKELY(result))
     {
       result += __mf_opts.crumple_zone;
@@ -179,11 +177,10 @@ WRAPPER(void *, realloc, void *buf, size
 			 __mf_opts.crumple_zone));
   result = (char *) CALL_REAL(realloc, base, size_with_crumple_zones);
 
-  __mf_state = old_state;      
-
   /* Ensure heap wiping doesn't occur during this peculiar
      unregister/reregister pair.  */
   LOCKTH ();
+  /* XXX: reentrancy! */
   saved_wipe_heap = __mf_opts.wipe_heap;
   __mf_opts.wipe_heap = 0;
 
@@ -224,14 +221,9 @@ WRAPPER(void, free, void *buf)
   static void *free_queue [__MF_FREEQ_MAX];
   static unsigned free_ptr = 0;
   static int freeq_initialized = 0;
-  enum __mf_state old_state;
   DECLARE(void * , free, void *);  
 
-  if (UNLIKELY (__mf_state != active))
-    {
-      CALL_REAL(free, buf);
-      return;
-    }
+  BEGIN_PROTECT(void *, free, buf);
 
   if (UNLIKELY(!freeq_initialized))
     {
@@ -247,9 +239,6 @@ WRAPPER(void, free, void *buf)
 
   __mf_unregister (buf, 0);
 
-  old_state = __mf_state;
-  __mf_state = reentrant;
-      
   if (UNLIKELY(__mf_opts.free_queue_length > 0))
     {
       
@@ -284,8 +273,6 @@ WRAPPER(void, free, void *buf)
 	}
       CALL_REAL(free, base);
     }
-  
-  __mf_state = old_state;
 }
 #endif
 
@@ -322,8 +309,6 @@ WRAPPER(void *, mmap, 
 		 (uintptr_t) result);
   */
 
-  __mf_state = old_state;
-
   if (result != (void *)-1)
     {
       /* Register each page as a heap object.  Why not register it all
@@ -375,8 +360,6 @@ WRAPPER(int , munmap, void *start, size_
 		 (uintptr_t) result);
   */
 
-  __mf_state = old_state;
-
   if (result == 0)
     {
       /* Unregister each page as a heap object.  */
@@ -479,6 +462,7 @@ WRAPPER(void *, alloca, size_t c)
 #ifdef WRAP_memcpy
 WRAPPER2(void *, memcpy, void *dest, const void *src, size_t n)
 {
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memcpy source");
   MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memcpy dest");
   return memcpy (dest, src, n);
@@ -489,6 +473,7 @@ WRAPPER2(void *, memcpy, void *dest, con
 #ifdef WRAP_memmove
 WRAPPER2(void *, memmove, void *dest, const void *src, size_t n)
 {
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memmove src");
   MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memmove dest");
   return memmove (dest, src, n);
@@ -498,6 +483,7 @@ WRAPPER2(void *, memmove, void *dest, co
 #ifdef WRAP_memset
 WRAPPER2(void *, memset, void *s, int c, size_t n)
 {
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "memset dest");
   return memset (s, c, n);
 }
@@ -506,6 +492,7 @@ WRAPPER2(void *, memset, void *s, int c,
 #ifdef WRAP_memcmp
 WRAPPER2(int, memcmp, const void *s1, const void *s2, size_t n)
 {
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "memcmp 1st arg");
   MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "memcmp 2nd arg");
   return memcmp (s1, s2, n);
@@ -515,6 +502,7 @@ WRAPPER2(int, memcmp, const void *s1, co
 #ifdef WRAP_memchr
 WRAPPER2(void *, memchr, const void *s, int c, size_t n)
 {
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memchr region");
   return memchr (s, c, n);
 }
@@ -523,6 +511,7 @@ WRAPPER2(void *, memchr, const void *s, 
 #ifdef WRAP_memrchr
 WRAPPER2(void *, memrchr, const void *s, int c, size_t n)
 {
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memrchr region");
   return memrchr (s, c, n);
 }
@@ -536,6 +525,7 @@ WRAPPER2(char *, strcpy, char *dest, con
      check anyways. */
 
   size_t n = strlen (src);
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(src, CLAMPADD(n, 1), __MF_CHECK_READ, "strcpy src"); 
   MF_VALIDATE_EXTENT(dest, CLAMPADD(n, 1), __MF_CHECK_WRITE, "strcpy dest");
   return strcpy (dest, src);
@@ -546,6 +536,7 @@ WRAPPER2(char *, strcpy, char *dest, con
 WRAPPER2(char *, strncpy, char *dest, const char *src, size_t n)
 {
   size_t len = strnlen (src, n);
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(src, len, __MF_CHECK_READ, "strncpy src");
   MF_VALIDATE_EXTENT(dest, len, __MF_CHECK_WRITE, "strncpy dest"); /* nb: strNcpy */
   return strncpy (dest, src, n);
@@ -557,7 +548,7 @@ WRAPPER2(char *, strcat, char *dest, con
 {
   size_t dest_sz;
   size_t src_sz;
-
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   dest_sz = strlen (dest);
   src_sz = strlen (src);  
   MF_VALIDATE_EXTENT(src, CLAMPADD(src_sz, 1), __MF_CHECK_READ, "strcat src");
@@ -593,7 +584,7 @@ WRAPPER2(char *, strncat, char *dest, co
 
   size_t src_sz;
   size_t dest_sz;
-
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   src_sz = strnlen (src, n);
   dest_sz = strnlen (dest, n);
   MF_VALIDATE_EXTENT(src, src_sz, __MF_CHECK_READ, "strncat src");
@@ -608,7 +599,7 @@ WRAPPER2(int, strcmp, const char *s1, co
 {
   size_t s1_sz;
   size_t s2_sz;
-
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   s1_sz = strlen (s1);
   s2_sz = strlen (s2);  
   MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcmp 1st arg");
@@ -622,7 +613,7 @@ WRAPPER2(int, strcasecmp, const char *s1
 {
   size_t s1_sz;
   size_t s2_sz;
-
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   s1_sz = strlen (s1);
   s2_sz = strlen (s2);  
   MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcasecmp 1st arg");
@@ -636,7 +627,7 @@ WRAPPER2(int, strncmp, const char *s1, c
 {
   size_t s1_sz;
   size_t s2_sz;
-
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   s1_sz = strnlen (s1, n);
   s2_sz = strnlen (s2, n);
   MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncmp 1st arg");
@@ -650,7 +641,7 @@ WRAPPER2(int, strncasecmp, const char *s
 {
   size_t s1_sz;
   size_t s2_sz;
-
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   s1_sz = strnlen (s1, n);
   s2_sz = strnlen (s2, n);
   MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncasecmp 1st arg");
@@ -665,7 +656,7 @@ WRAPPER2(char *, strdup, const char *s)
   DECLARE(void *, malloc, size_t sz);
   char *result;
   size_t n = strlen (s);
-
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strdup region");
   result = (char *)CALL_REAL(malloc, 
 			     CLAMPADD(CLAMPADD(n,1),
@@ -689,7 +680,7 @@ WRAPPER2(char *, strndup, const char *s,
   DECLARE(void *, malloc, size_t sz);
   char *result;
   size_t sz = strnlen (s, n);
-
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(s, sz, __MF_CHECK_READ, "strndup region"); /* nb: strNdup */
 
   /* note: strndup still adds a \0, even with the N limit! */
@@ -713,7 +704,7 @@ WRAPPER2(char *, strndup, const char *s,
 WRAPPER2(char *, strchr, const char *s, int c)
 {
   size_t n;
-
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   n = strlen (s);
   MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strchr region");
   return strchr (s, c);
@@ -724,7 +715,7 @@ WRAPPER2(char *, strchr, const char *s, 
 WRAPPER2(char *, strrchr, const char *s, int c)
 {
   size_t n;
-
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   n = strlen (s);
   MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strrchr region");
   return strrchr (s, c);
@@ -736,7 +727,7 @@ WRAPPER2(char *, strstr, const char *hay
 {
   size_t haystack_sz;
   size_t needle_sz;
-
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   haystack_sz = strlen (haystack);
   needle_sz = strlen (needle);
   MF_VALIDATE_EXTENT(haystack, CLAMPADD(haystack_sz, 1), __MF_CHECK_READ, "strstr haystack");
@@ -750,6 +741,7 @@ WRAPPER2(void *, memmem, 
 	const void *haystack, size_t haystacklen,
 	const void *needle, size_t needlelen)
 {
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(haystack, haystacklen, __MF_CHECK_READ, "memmem haystack");
   MF_VALIDATE_EXTENT(needle, needlelen, __MF_CHECK_READ, "memmem needle");
   return memmem (haystack, haystacklen, needle, needlelen);
@@ -760,6 +752,7 @@ WRAPPER2(void *, memmem, 
 WRAPPER2(size_t, strlen, const char *s)
 {
   size_t result = strlen (s);
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(s, CLAMPADD(result, 1), __MF_CHECK_READ, "strlen region");
   return result;
 }
@@ -769,6 +762,7 @@ WRAPPER2(size_t, strlen, const char *s)
 WRAPPER2(size_t, strnlen, const char *s, size_t n)
 {
   size_t result = strnlen (s, n);
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(s, result, __MF_CHECK_READ, "strnlen region");
   return result;
 }
@@ -777,6 +771,7 @@ WRAPPER2(size_t, strnlen, const char *s,
 #ifdef WRAP_bzero
 WRAPPER2(void, bzero, void *s, size_t n)
 {
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
   bzero (s, n);
 }
@@ -786,6 +781,7 @@ WRAPPER2(void, bzero, void *s, size_t n)
 #undef bcopy
 WRAPPER2(void, bcopy, const void *src, void *dest, size_t n)
 {
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
   MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
   bcopy (src, dest, n);
@@ -796,6 +792,7 @@ WRAPPER2(void, bcopy, const void *src, v
 #undef bcmp
 WRAPPER2(int, bcmp, const void *s1, const void *s2, size_t n)
 {
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
   MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
   return bcmp (s1, s2, n);
@@ -806,6 +803,7 @@ WRAPPER2(int, bcmp, const void *s1, cons
 WRAPPER2(char *, index, const char *s, int c)
 {
   size_t n = strlen (s);
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
   return index (s, c);
 }
@@ -815,6 +813,7 @@ WRAPPER2(char *, index, const char *s, i
 WRAPPER2(char *, rindex, const char *s, int c)
 {
   size_t n = strlen (s);
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
   return rindex (s, c);
 }
@@ -833,6 +832,7 @@ WRAPPER2(char *, asctime, struct tm *tm)
 {
   static char *reg_result = NULL;
   char *result;
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(tm, sizeof (struct tm), __MF_CHECK_READ, "asctime tm");
   result = asctime (tm);
   if (reg_result == NULL)
@@ -849,6 +849,7 @@ WRAPPER2(char *, ctime, const time_t *ti
 {
   static char *reg_result = NULL;
   char *result;
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "ctime time");
   result = ctime (timep);
   if (reg_result == NULL)
@@ -867,6 +868,7 @@ WRAPPER2(struct tm*, localtime, const ti
 {
   static struct tm *reg_result = NULL;
   struct tm *result;
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "localtime time");
   result = localtime (timep);
   if (reg_result == NULL)
@@ -883,6 +885,7 @@ WRAPPER2(struct tm*, gmtime, const time_
 {
   static struct tm *reg_result = NULL;
   struct tm *result;
+  TRACE ("mf: %s\n", __PRETTY_FUNCTION__);
   MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "gmtime time");
   result = gmtime (timep);
   if (reg_result == NULL)
@@ -996,8 +999,7 @@ WRAPPER(int, pthread_create, pthread_t *
 
   TRACE ("mf: pthread_create\n");
 
-  LOCKTH();
-
+  /* LOCKTH(); */
   /* Garbage collect dead thread stacks.  */
   for (i = 0; i < PTHREAD_THREADS_MAX; i++)
     {
@@ -1024,7 +1026,7 @@ WRAPPER(int, pthread_create, pthread_t *
 	  break;
 	}
     }
-  UNLOCKTH();
+  /* UNLOCKTH(); */
 
   if (i == PTHREAD_THREADS_MAX) /* no slots free - simulated out-of-memory.  */
     {
@@ -1042,6 +1044,7 @@ WRAPPER(int, pthread_create, pthread_t *
     pthread_attr_init (& override_attr);
 
   /* Get supplied attributes.  Give up on error.  */
+  /* XXX: consider using POSIX2K attr_getstack() */
   if (pthread_attr_getstackaddr (& override_attr, & override_stack) != 0 ||
       pthread_attr_getstacksize (& override_attr, & override_stacksize) != 0)
     {
@@ -1082,10 +1085,11 @@ WRAPPER(int, pthread_create, pthread_t *
 	(((uintptr_t) override_stack + override_stacksize - alignment)
 	 & (~(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) != 0)
 	{
-	  /* Er, what now?  */
+	  /* This should not happen.  */
 	  CALL_REAL (free, pi->stack);
 	  pi->stack = NULL;
 	  errno = EAGAIN;
Index: mf-impl.h
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-impl.h,v
retrieving revision 1.1.2.19
diff -u -p -w -s -r1.1.2.19 mf-impl.h
--- mf-impl.h	12 May 2003 14:16:21 -0000	1.1.2.19
+++ mf-impl.h	16 May 2003 19:09:34 -0000
@@ -200,7 +200,10 @@ enum __mf_dynamic_index
 
 #ifdef LIBMUDFLAPTH
 extern pthread_mutex_t __mf_biglock;
-#define LOCKTH() do { int rc = pthread_mutex_lock (& __mf_biglock); \
+#define LOCKTH() do { extern unsigned long __mf_lock_contention; \
+                      int rc = pthread_mutex_trylock (& __mf_biglock); \
+                      if (rc) { __mf_lock_contention ++; \
+                                rc = pthread_mutex_lock (& __mf_biglock); } \
                       assert (rc==0); } while (0)
 #define UNLOCKTH() do { int rc = pthread_mutex_unlock (& __mf_biglock); \
                         assert (rc==0); } while (0)
@@ -209,7 +212,7 @@ extern pthread_mutex_t __mf_biglock;
 #define UNLOCKTH() do {} while (0)
 #endif
 
-extern enum __mf_state __mf_state;
+extern /* volatile? */ enum __mf_state __mf_state;
 extern struct __mf_options __mf_opts;
 
 /* ------------------------------------------------------------------------ */
@@ -223,18 +226,12 @@ extern struct __mf_options __mf_opts;
 #define VERBOSE_TRACE(...)                         \
   if (UNLIKELY (__mf_opts.verbose_trace)) \
     { \
-      enum __mf_state _ts = __mf_state; \
-      __mf_state = reentrant; \
       fprintf (stderr, __VA_ARGS__); \
-      __mf_state = _ts; \
     }
 #define TRACE(...)                         \
   if (UNLIKELY (__mf_opts.trace_mf_calls)) \
     { \
-      enum __mf_state _ts = __mf_state; \
-      __mf_state = reentrant; \
       fprintf (stderr, __VA_ARGS__); \
-      __mf_state = _ts; \
     }
 
 
Index: mf-runtime.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-runtime.c,v
retrieving revision 1.1.2.35
diff -u -p -w -s -r1.1.2.35 mf-runtime.c
--- mf-runtime.c	12 May 2003 14:16:21 -0000	1.1.2.35
+++ mf-runtime.c	16 May 2003 19:09:35 -0000
@@ -57,15 +57,18 @@ XXX: libgcc license?
 #define __MF_VIOL_WATCH 5
 
 /* Protect against recursive calls. */
-#define BEGIN_RECURSION_PROTECT           \
-  enum __mf_state old_state;              \
-  if (UNLIKELY (__mf_state == reentrant)) \
-    return;                               \
-  old_state = __mf_state;                 \
-  __mf_state = reentrant;
-
-#define END_RECURSION_PROTECT             \
-  __mf_state = old_state;
+#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)
 
 
 
@@ -115,6 +118,10 @@ static unsigned long __mf_total_unregist
 static unsigned long __mf_count_violation [__MF_VIOL_WATCH+1];
 static unsigned long __mf_sigusr1_received;
 static unsigned long __mf_sigusr1_handled;
+/* not static */ unsigned long __mf_reentrancy;
+#ifdef LIBMUDFLAPTH
+/* not static */ unsigned long __mf_lock_contention;
+#endif
 
 
 /* ------------------------------------------------------------------------ */
@@ -388,7 +395,9 @@ __mf_set_options (const char *optstr)
 {
   int rc;
   LOCKTH ();
+  BEGIN_RECURSION_PROTECT ();
   rc = __mfu_set_options (optstr);
+  END_RECURSION_PROTECT ();
   UNLOCKTH ();
   return rc;
 }
@@ -482,6 +491,7 @@ __mfu_set_options (const char *optstr)
   __mf_opts.free_queue_length &= (__MF_FREEQ_MAX - 1);
 
   /* Clear the lookup cache, in case the parameters got changed.  */
+  /* XXX: race */
   memset (__mf_lookup_cache, 0, sizeof(__mf_lookup_cache));
   /* void slot 0 */
   __mf_lookup_cache[0].low = MAXPTR;
@@ -585,7 +595,7 @@ void __mf_init ()
   __mf_describe_object (NULL);
 
 #define REG_RESERVED(obj) \
-  __mfu_register (& obj, sizeof(obj), __MF_TYPE_NOACCESS, # obj)
+  __mf_register (& obj, sizeof(obj), __MF_TYPE_NOACCESS, # obj)
 
   REG_RESERVED (__mf_lookup_cache);
   REG_RESERVED (__mf_lc_mask);
@@ -593,19 +603,19 @@ void __mf_init ()
   /* XXX: others of our statics?  */
 
   /* Prevent access to *NULL. */
-  __mfu_register (MINPTR, 1, __MF_TYPE_NOACCESS, "NULL");
+  __mf_register (MINPTR, 1, __MF_TYPE_NOACCESS, "NULL");
   __mf_lookup_cache[0].low = (uintptr_t) -1;
 
   /* XXX: bad hack: assumes Linux process layout */
   if (__mf_opts.heur_argv_environ)
     {
       int foo = 0;
-      __mfu_register (& foo,
+      __mf_register (& foo,
 		      (size_t) 0xC0000000 - (size_t) (& foo),
 		      __MF_TYPE_GUESS,
 		      "argv/environ area");
       /* XXX: separate heuristic? */
-      __mfu_register (& errno, sizeof (errno),
+      __mf_register (& errno, sizeof (errno),
 		      __MF_TYPE_GUESS,
 		      "errno area");
     }
@@ -627,7 +637,9 @@ void __mf_fini ()
 void __mf_check (void *ptr, size_t sz, int type, const char *location)
 {
   LOCKTH ();
+  BEGIN_RECURSION_PROTECT ();
   __mfu_check (ptr, sz, type, location);
+  END_RECURSION_PROTECT ();
   UNLOCKTH ();
 }
 
@@ -641,8 +653,6 @@ void __mfu_check (void *ptr, size_t sz, 
   uintptr_t ptr_high = CLAMPSZ (ptr, sz);
   struct __mf_cache old_entry = *entry;
 
-  BEGIN_RECURSION_PROTECT;
-
   if (UNLIKELY (__mf_opts.sigusr1_report))
     __mf_sigusr1_respond ();
 
@@ -867,8 +877,6 @@ void __mfu_check (void *ptr, size_t sz, 
 	__mf_lookup_cache_reusecount [entry_idx] ++;    
     }
   
-  END_RECURSION_PROTECT;
-  
   if (UNLIKELY (judgement < 0))
     __mf_violation (ptr, sz,
 		    (uintptr_t) __builtin_return_address (0), location,
@@ -939,7 +947,9 @@ void
 __mf_register (void *ptr, size_t sz, int type, const char *name)
 {
   LOCKTH ();
+  BEGIN_RECURSION_PROTECT ();
   __mfu_register (ptr, sz, type, name);
+  END_RECURSION_PROTECT ();
   UNLOCKTH ();
 }
 
@@ -947,8 +957,6 @@ __mf_register (void *ptr, size_t sz, int
 void
 __mfu_register (void *ptr, size_t sz, int type, const char *name)
 {
-  /* if (UNLIKELY (!(__mf_state == active || __mf_state == starting))) return; */
-
   TRACE ("mf: register ptr=%08lx size=%lu type=%x name='%s'\n", ptr, sz, 
 	type, name ? name : "");
 
@@ -960,7 +968,6 @@ __mfu_register (void *ptr, size_t sz, in
 				type] += sz;
     }
 
-
   if (UNLIKELY (__mf_opts.sigusr1_report))
     __mf_sigusr1_respond ();
 
@@ -977,6 +984,7 @@ __mfu_register (void *ptr, size_t sz, in
     case mode_populate:
       /* Clear the cache.  */
       /* XXX: why the entire cache? */
+      /* XXX: race */
       memset (__mf_lookup_cache, 0, sizeof(__mf_lookup_cache));
       /* void slot 0 */
       __mf_lookup_cache[0].low = MAXPTR;
@@ -990,8 +998,6 @@ __mfu_register (void *ptr, size_t sz, in
 	uintptr_t high = CLAMPSZ (ptr, sz);
 	uintptr_t pc = (uintptr_t) __builtin_return_address (0);
 	
-	BEGIN_RECURSION_PROTECT;
-	
 	/* Treat unknown size indication as 1.  */
 	if (UNLIKELY (sz == 0)) sz = 1;
 	
@@ -1014,8 +1020,7 @@ __mfu_register (void *ptr, size_t sz, in
 		VERBOSE_TRACE ("mf: duplicate static reg %08lx-%08lx `%s'\n", 
 			       low, high, 
 			       (ovr_obj->data.name ? ovr_obj->data.name : ""));
-		END_RECURSION_PROTECT;
-		return;
+		break;
 	      }
 
 	    /* Quietly accept a single duplicate registration for
@@ -1027,8 +1032,7 @@ __mfu_register (void *ptr, size_t sz, in
 	      {
 		/* do nothing */
 		VERBOSE_TRACE ("mf: duplicate guess reg %08lx-%08lx\n", low, high);
-		END_RECURSION_PROTECT;
-		return;
+		break;
 	      }
 
 	    /* Quietly accept new a guess registration that overlaps
@@ -1058,7 +1062,7 @@ __mfu_register (void *ptr, size_t sz, in
 
 		/* Add GUESS regions between the holes: before each
 		   overlapping region.  */
-		END_RECURSION_PROTECT;
+
 		next_low = low;
 		/* This makes use of the assumption that __mf_find_objects() returns
 		   overlapping objects in an increasing sequence.  */
@@ -1101,7 +1105,6 @@ __mfu_register (void *ptr, size_t sz, in
   		   violation), or if no further overlap occurs.  The
   		   located GUESS region should end up being split up
   		   in any case.  */
-		END_RECURSION_PROTECT;
 		__mfu_unregister ((void *) old_low, old_high-old_low+1);
 		__mfu_register ((void *) low, sz, type, name);
 		__mfu_register ((void *) old_low, old_high-old_low+1,
@@ -1128,7 +1131,6 @@ __mfu_register (void *ptr, size_t sz, in
 	/* We could conceivably call __mf_check() here to prime the cache,
 	   but then the read_count/write_count field is not reliable.  */
 	
-	END_RECURSION_PROTECT;
 	break;
       }
     } /* end switch (__mf_opts.mudflap_mode) */
@@ -1139,7 +1141,9 @@ void
 __mf_unregister (void *ptr, size_t sz)
 {
   LOCKTH ();
+  BEGIN_RECURSION_PROTECT ();
   __mfu_unregister (ptr, sz);
+  END_RECURSION_PROTECT ();
   UNLOCKTH ();
 }
 
@@ -1149,8 +1153,6 @@ __mfu_unregister (void *ptr, size_t sz)
 {
   DECLARE (void, free, void *ptr);
 
-  BEGIN_RECURSION_PROTECT;
-
   if (UNLIKELY (__mf_opts.sigusr1_report))
   __mf_sigusr1_respond ();
 
@@ -1169,6 +1171,7 @@ __mfu_unregister (void *ptr, size_t sz)
 
     case mode_populate:
       /* Clear the cache.  */
+      /* XXX: race */
       memset (__mf_lookup_cache, 0, sizeof(__mf_lookup_cache));
       /* void slot 0 */
       __mf_lookup_cache[0].low = MAXPTR;
@@ -1194,11 +1197,10 @@ __mfu_unregister (void *ptr, size_t sz)
 	if (UNLIKELY (num_overlapping_objs != 1 ||
 		      ptr != old_obj->data.low)) /* XXX: what about sz? */
 	  {
-	    END_RECURSION_PROTECT;
 	    __mf_violation (ptr, sz,
 			    (uintptr_t) __builtin_return_address (0), NULL,
 			    __MF_VIOL_UNREGISTER);
-	    return;
+	    break;
 	  }
 
 	__mf_unlink_object (old_obj);
@@ -1290,8 +1292,6 @@ __mfu_unregister (void *ptr, size_t sz)
       __mf_count_unregister ++;
       __mf_total_unregister_size += sz;
     }
-
-  END_RECURSION_PROTECT;
 }
 
 /* ------------------------------------------------------------------------ */
@@ -1481,6 +1481,7 @@ __mf_adapt_cache ()
     {
       __mf_lc_mask = new_mask;
       __mf_lc_shift = new_shift;
+      /* XXX: race */
       memset (__mf_lookup_cache, 0, sizeof(__mf_lookup_cache));
       /* void slot 0 */
       __mf_lookup_cache[0].low = MAXPTR;
@@ -1827,15 +1828,15 @@ void
 __mf_report ()
 {
   LOCKTH ();
+  BEGIN_RECURSION_PROTECT ();
   __mfu_report ();
+  END_RECURSION_PROTECT ();
   UNLOCKTH ();
 }
 
 void
 __mfu_report ()
 {
-  /* if (UNLIKELY (__mf_state == active)) return; */
-
   if (__mf_opts.collect_stats)
     {
       fprintf (stderr,
@@ -1855,6 +1856,13 @@ __mfu_report ()
 	       __mf_count_violation[2], __mf_count_violation[3],
 	       __mf_count_violation[4]);
 
+      fprintf (stderr,
+	       "calls with reentrancy: %lu\n", __mf_reentrancy);
+#ifdef LIBMUDFLAPTH
+      fprintf (stderr,
+	       "           lock contention: %lu\n", __mf_lock_contention);
+#endif
+
       /* Lookup cache stats.  */
       {
 	unsigned i;
@@ -2005,7 +2013,6 @@ __mf_violation (void *ptr, size_t sz, ui
   char buf [128];
   static unsigned violation_number;
   DECLARE(void, free, void *ptr);
-  BEGIN_RECURSION_PROTECT;
 
   TRACE ("mf: violation pc=%08lx location=%s type=%d ptr=%08lx size=%lu\n", pc, 
 	 (location != NULL ? location : ""), type, ptr, sz);
@@ -2146,8 +2153,6 @@ __mf_violation (void *ptr, size_t sz, ui
       gdb dies, then starting a new one is appropriate.)  */
       break;
     }
-  
-  END_RECURSION_PROTECT;
 }
 
 /* ------------------------------------------------------------------------ */
@@ -2157,7 +2162,9 @@ unsigned __mf_watch (void *ptr, size_t s
 {
   unsigned rc;
   LOCKTH ();
+  BEGIN_RECURSION_PROTECT ();
   rc = __mf_watch_or_not (ptr, sz, 1);
+  END_RECURSION_PROTECT ();
   UNLOCKTH ();
   return rc;
 }
Index: testsuite/lib/libmudflap.exp
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/testsuite/lib/Attic/libmudflap.exp,v
retrieving revision 1.1.2.2
diff -u -p -w -s -r1.1.2.2 libmudflap.exp
--- testsuite/lib/libmudflap.exp	10 Mar 2003 22:29:58 -0000	1.1.2.2
+++ testsuite/lib/libmudflap.exp	16 May 2003 19:09:35 -0000
@@ -227,5 +227,11 @@ proc prune_gcc_output { text } {
 
     regsub -all {(^|\n)[^\n]*ld: warning: libgcc_s[^\n]*not found[^\n]*try using[^\n]*} $text "" text
 
+    regsub -all {(^|\n)[^\n]*In function.*pthread_create[^\n]*} $text "" text
+
+    regsub -all {(^|\n)[^\n]*the use of .pthread.*is deprecated[^\n]*} $text "" text
+
+    regsub -all {(^|\n)[^\n]*Dwarf Error:.*FORM value: 14[^\n]*} $text "" text
+
     return $text
 }
Index: testsuite/libmudflap.c/cfrags.exp
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/testsuite/libmudflap.c/Attic/cfrags.exp,v
retrieving revision 1.1.2.1
diff -u -p -w -s -r1.1.2.1 cfrags.exp
--- testsuite/libmudflap.c/cfrags.exp	26 Feb 2003 19:00:37 -0000	1.1.2.1
+++ testsuite/libmudflap.c/cfrags.exp	16 May 2003 19:09:35 -0000
@@ -7,7 +7,7 @@ global srcdir
 foreach flags [list {} {-static} {-O2} {-O3}] {
     foreach srcfile [lsort [glob -nocomplain ${srcdir}/libmudflap.c/*.c]] {
 	set bsrc [file tail $srcfile]
-	setenv MUDFLAP_OPTIONS "-no-heur-proc-map -no-heur-argv-environ -viol-segv"
+	setenv MUDFLAP_OPTIONS "-no-heur-argv-environ -viol-segv"
 	dg-runtest $srcfile $flags "-fmudflap"
     }
 }
Index: testsuite/libmudflap.cth/cthfrags.exp
===================================================================
RCS file: testsuite/libmudflap.cth/cthfrags.exp
diff -N testsuite/libmudflap.cth/cthfrags.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/libmudflap.cth/cthfrags.exp	16 May 2003 19:09:35 -0000
@@ -0,0 +1,23 @@
+
+libmudflap-init [find_gcc]
+
+dg-init
+
+global srcdir
+foreach flags [list {} {-static} {-O2} {-O3}] {
+    foreach srcfile [lsort [glob -nocomplain ${srcdir}/libmudflap.cth/*.c]] {
+	set bsrc [file tail $srcfile]
+	setenv MUDFLAP_OPTIONS "-no-heur-argv-environ -viol-segv"
+	if {$libmudflapth} then {
+	    # --noinhibit-exec works around a ld problem that causes
+	    # "Dwarf Error: Invalid or unhandled FORM value: 14"
+	    # to fail builds unnecessarily.
+	    dg-runtest $srcfile $flags "-fmudflapth -Wl,--noinhibit-exec"
+	} else {
+	    if {$flags != ""} {set f " ($flags)"} {set f ""}
+            untested "libmudflap.cth/$bsrc$f"
+	}
+    }
+}
+
+dg-finish

Index: testsuite/libmudflap.cth/pass37-frag.c
===================================================================
RCS file: testsuite/libmudflap.cth/pass37-frag.c
diff -N testsuite/libmudflap.cth/pass37-frag.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/libmudflap.cth/pass37-frag.c	16 May 2003 19:33:09 -0000
@@ -0,0 +1,50 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <sched.h>
+
+static void *
+func (void *p)
+{
+  int thr = (int) p;
+  unsigned i;
+  
+  for (i=0; i<100; i++)
+    {
+      /* fprintf (stderr, "thread %d iteration %u REG\n", thr, i); */
+      {
+	int array[17];
+	unsigned x = i % (sizeof(array)/sizeof(array[0]));
+	/* VRP could prove that x is within [0,16], but until then, the
+	   following access will ensure that array[] is registered to
+	   libmudflap. */
+	array[x] = i;
+      }
+      /* fprintf (stderr, "thread %d iteration %u UNREG/YIELD\n", thr, i); */
+      sched_yield (); /* sleep (1); */
+    }
+
+  return (NULL);
+}
+
+
+int main ()
+{
+  int rc;
+  unsigned i;
+  pthread_t	threads[10];
+
+  for (i=0; i<sizeof(threads)/sizeof(threads[0]); i++)
+    {
+      rc = pthread_create (& threads[i], NULL, func, (void *) i);
+      if (rc) abort();
+    }
+
+  for (i=0; i<sizeof(threads)/sizeof(threads[0]); i++)
+    {
+      rc = pthread_join (threads[i], NULL);
+      if (rc) abort();      
+    }
+
+  return 0;
+}


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