[tree-ssa libmudflap] multithreading baby-steps, more wrappers
Frank Ch. Eigler
fche@redhat.com
Mon Apr 28 15:16:00 GMT 2003
Hi -
The attached patch includes some libmudflap cleanup, some more libc
wrapper functions, and baby steps toward multithreading support. Eyal
has reported, and I've reproduced, odd hangs during linux glibc pthread
creation. This was caused by the libmudflap registration functions
using way too much stack during the allocation of the thread stacks.
It turns out that there was a logic bug in the recursion, which made it
do a lot more work than necessary. Now at least we get past thread
creation, though many real problems remain unsolved.
- FChE
+2002-04-28 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile.am (HOOKOBJS): Add *time related hooks.
+ * configure.in: Look for pthreads.h header.
+ * mf-hooks.c (asctime, ctime, gmtime, localtime): New wrappers.
+ * mf-runtime.c: Begin sketching some pthreads support.
+ (__mf_usage): Check for -lpthread presence.
+ (__mf_unregister): Confirm matching unregistration base.
+ (__mf_find_objects_rec): Reduce unnecessary recursion.
+ * mf-runtime.h.in: Add "nothrow" attribute to functions. Add
+ #defines for new hook functions.
+ * mf-impl.h: Corresponding changes.
+ * config.h.in, configure, Makefile.in: Regenerated.
Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/Makefile.am,v
retrieving revision 1.1.2.26
diff -u -w -s -p -r1.1.2.26 Makefile.am
--- Makefile.am 15 Apr 2003 19:55:29 -0000 1.1.2.26
+++ Makefile.am 28 Apr 2003 15:11:31 -0000
@@ -51,7 +51,11 @@ HOOKOBJS = \
rindex-hook.lo \
mmap-hook.lo \
munmap-hook.lo \
- alloca-hook.lo
+ alloca-hook.lo \
+ asctime-hook.lo \
+ ctime-hook.lo \
+ gmtime-hook.lo \
+ localtime-hook.lo
#.NOTPARALLEL: # Otherwise the following loop will be executed in parallel!
$(HOOKOBJS): mf-hooks.c mf-runtime.h mf-impl.h
Index: configure.in
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/configure.in,v
retrieving revision 1.1.2.13
diff -u -w -s -p -r1.1.2.13 configure.in
--- configure.in 15 Apr 2003 19:55:29 -0000 1.1.2.13
+++ configure.in 28 Apr 2003 15:11:33 -0000
@@ -36,7 +36,7 @@ else
fi
AC_SUBST(MF_HAVE_UINTPTR_T)
-AC_CHECK_HEADERS(stdint.h execinfo.h signal.h)
+AC_CHECK_HEADERS(stdint.h execinfo.h signal.h pthread.h)
AC_CHECK_FUNCS(backtrace backtrace_symbols gettimeofday signal)
AC_CHECK_LIB(dl, dlsym)
Index: mf-hooks.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-hooks.c,v
retrieving revision 1.1.2.30
diff -u -w -s -p -r1.1.2.30 mf-hooks.c
--- mf-hooks.c 15 Apr 2003 16:52:47 -0000 1.1.2.30
+++ mf-hooks.c 28 Apr 2003 15:11:33 -0000
@@ -14,6 +14,7 @@ XXX: libgcc license?
#include <sys/types.h>
#include <unistd.h>
#include <assert.h>
+#include <time.h>
#include "mf-runtime.h"
#include "mf-impl.h"
@@ -817,5 +818,72 @@ WRAPPER2(char *, rindex, const char *s,
/* XXX: setjmp, longjmp */
+
+#ifdef WRAP_asctime
+WRAPPER2(char *, asctime, struct tm *tm)
+{
+ static char *reg_result = NULL;
+ char *result;
+ MF_VALIDATE_EXTENT(tm, sizeof (struct tm), __MF_CHECK_READ, "asctime tm");
+ result = asctime (tm);
+ if (reg_result == NULL)
+ {
+ __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "asctime string");
+ reg_result = result;
+ }
+ return result;
+}
+#endif
+
+#ifdef WRAP_ctime
+WRAPPER2(char *, ctime, const time_t *timep)
+{
+ static char *reg_result = NULL;
+ char *result;
+ MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "ctime time");
+ result = ctime (timep);
+ if (reg_result == NULL)
+ {
+ /* XXX: what if asctime and ctime return the same static ptr? */
+ __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "ctime string");
+ reg_result = result;
+ }
+ return result;
+}
+#endif
+
+
+#ifdef WRAP_localtime
+WRAPPER2(struct tm*, localtime, const time_t *timep)
+{
+ static struct tm *reg_result = NULL;
+ struct tm *result;
+ MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "localtime time");
+ result = localtime (timep);
+ if (reg_result == NULL)
+ {
+ __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "localtime tm");
+ reg_result = result;
+ }
+ return result;
+}
+#endif
+
+#ifdef WRAP_gmtime
+WRAPPER2(struct tm*, gmtime, const time_t *timep)
+{
+ static struct tm *reg_result = NULL;
+ struct tm *result;
+ MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "gmtime time");
+ result = gmtime (timep);
+ if (reg_result == NULL)
+ {
+ __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "gmtime tm");
+ reg_result = result;
+ }
+ return result;
+}
+#endif
+
/* ------------------------------------------------------------------------ */
Index: mf-impl.h
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-impl.h,v
retrieving revision 1.1.2.17
diff -u -w -s -p -r1.1.2.17 mf-impl.h
--- mf-impl.h 2 Apr 2003 16:21:32 -0000 1.1.2.17
+++ mf-impl.h 28 Apr 2003 15:11:33 -0000
@@ -17,6 +17,10 @@
#error "Do not compile this file with -fmudflap!"
#endif
+#if HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
/* Private definitions related to mf-runtime.h */
@@ -181,6 +185,9 @@ struct __mf_dynamic
/* Private global variables. */
/* ------------------------------------------------------------------------ */
+#ifdef HAVE_PTHREAD_H
+extern pthread_mutex_t __mf_biglock;
+#endif
extern enum __mf_state __mf_state;
extern struct __mf_options __mf_opts;
#ifdef PIC
Index: mf-runtime.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-runtime.c,v
retrieving revision 1.1.2.33
diff -u -w -s -p -r1.1.2.33 mf-runtime.c
--- mf-runtime.c 15 Apr 2003 19:55:29 -0000 1.1.2.33
+++ mf-runtime.c 28 Apr 2003 15:11:34 -0000
@@ -31,6 +31,8 @@ XXX: libgcc license?
#include "mf-impl.h"
+/* ------------------------------------------------------------------------ */
+
#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
@@ -39,9 +41,6 @@ XXX: libgcc license?
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
-#ifdef _MUDFLAP
-#error "Do not compile this file with -fmudflap!"
-#endif
/* ------------------------------------------------------------------------ */
/* Utility macros */
@@ -72,27 +71,30 @@ XXX: libgcc license?
/* ------------------------------------------------------------------------ */
/* Required globals. */
-#ifndef LOOKUP_CACHE_MASK_DFL
#define LOOKUP_CACHE_MASK_DFL 1023
-#endif
-#ifndef LOOKUP_CACHE_SIZE_MAX
#define LOOKUP_CACHE_SIZE_MAX 4096 /* Allows max CACHE_MASK 0x0FFF */
-#endif
-#ifndef LOOKUP_CACHE_SHIFT_DFL
#define LOOKUP_CACHE_SHIFT_DFL 2
-#endif
struct __mf_cache __mf_lookup_cache [LOOKUP_CACHE_SIZE_MAX];
uintptr_t __mf_lc_mask = LOOKUP_CACHE_MASK_DFL;
unsigned char __mf_lc_shift = LOOKUP_CACHE_SHIFT_DFL;
#define LOOKUP_CACHE_SIZE (__mf_lc_mask + 1)
+
struct __mf_options __mf_opts;
enum __mf_state __mf_state = inactive;
+#ifdef HAVE_PTHREAD_H
+pthread_mutex_t __mf_biglock = PTHREAD_MUTEX_INITIALIZER;
+#endif
#ifdef PIC
struct __mf_dynamic __mf_dynamic;
#endif
+#if HAVE_PTHREAD_H
+#pragma weak pthread_create
+const void *threads_active_p = (void *) pthread_create;
+#endif
+
static void __mf_sigusr1_respond ();
@@ -256,7 +258,7 @@ __mf_usage ()
struct option *opt;
fprintf (stderr,
- "This is a GCC \"mudflap\" memory-checked binary.\n"
+ "This is a %sGCC \"mudflap\" memory-checked binary.\n"
"Mudflap is Copyright (C) 2002-2003 Free Software Foundation, Inc.\n"
"\n"
"The mudflap code can be controlled by an environment variable:\n"
@@ -266,7 +268,13 @@ __mf_usage ()
"\n"
"where <options> is a space-separated list of \n"
"any of the following options. Use `-no-OPTION' to disable options.\n"
- "\n");
+ "\n",
+#if HAVE_PTHREAD_H
+ (threads_active_p ? "multi-threaded " : "single-threaded ")
+#else
+ ""
+#endif
+ );
for (opt = options; opt->name; opt++)
{
@@ -1116,10 +1124,11 @@ __mf_unregister (void *ptr, size_t sz)
/* XXX: handle unregistration of big old GUESS region, that has since
been splintered. */
+ old_obj = objs[0];
- if (UNLIKELY (num_overlapping_objs != 1))
+ if (UNLIKELY (num_overlapping_objs != 1 ||
+ ptr != old_obj->data.low)) /* XXX: what about sz? */
{
- /* XXX: also: should check/assert ptr == old_obj->low ? */
END_RECURSION_PROTECT;
__mf_violation (ptr, sz,
(uintptr_t) __builtin_return_address (0), NULL,
@@ -1127,8 +1136,6 @@ __mf_unregister (void *ptr, size_t sz)
return;
}
- old_obj = objs[0];
-
__mf_unlink_object (old_obj);
__mf_uncache_object (& old_obj->data);
@@ -1418,8 +1425,6 @@ __mf_adapt_cache ()
-
-
/* __mf_find_object[s] */
/* Find overlapping live objecs between [low,high]. Return up to
@@ -1443,7 +1448,8 @@ __mf_find_objects_rec (uintptr_t low, ui
/* Traverse down left subtree. */
count = 0;
if (low < node->data.low)
- count += __mf_find_objects_rec (low, high, & node->left, objs, max_objs);
+ count += __mf_find_objects_rec (low, min(high, node->data.low),
+ & node->left, objs, max_objs);
/* Track the used slots of objs[]. */
if (count < max_objs)
@@ -1470,7 +1476,8 @@ __mf_find_objects_rec (uintptr_t low, ui
/* Traverse down right subtree. */
if (high > node->data.high)
- count += __mf_find_objects_rec (low, high, & node->right, objs, max_objs);
+ count += __mf_find_objects_rec (max (low, node->data.high), high,
+ & node->right, objs, max_objs);
/* There is no need to manipulate objs/max_objs any further. */
Index: mf-runtime.h.in
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-runtime.h.in,v
retrieving revision 1.1.2.11
diff -u -w -s -p -r1.1.2.11 mf-runtime.h.in
--- mf-runtime.h.in 15 Apr 2003 19:55:29 -0000 1.1.2.11
+++ mf-runtime.h.in 28 Apr 2003 15:11:34 -0000
@@ -1,8 +1,7 @@
-#ifndef MF_RUNTIME_H
-#define MF_RUNTIME_H
-
/* Public libmudflap declarations -*- C -*- */
+#ifndef MF_RUNTIME_H
+#define MF_RUNTIME_H
#if @MF_HAVE_STDINT_H@ /* autoconf HAVE_STDINT_H */
#include <stdint.h>
@@ -46,9 +45,11 @@ extern unsigned char __mf_lc_shift;
extern "C" {
#endif
-extern void __mf_check (void *ptr, size_t sz, int type, const char *location);
-extern void __mf_register (void *ptr, size_t sz, int type, const char *name);
-extern void __mf_unregister (void *ptr, size_t sz);
+extern void __mf_check (void *ptr, size_t sz, int type, const char *location)
+ __attribute((nothrow));
+extern void __mf_register (void *ptr, size_t sz, int type, const char *name)
+ __attribute((nothrow));
+extern void __mf_unregister (void *ptr, size_t sz) __attribute((nothrow));
extern unsigned __mf_watch (void *ptr, size_t sz);
extern unsigned __mf_unwatch (void *ptr, size_t sz);
extern void __mf_report ();
@@ -87,6 +88,10 @@ extern int __mf_set_options (const char
#define bcmp __mfwrap_bcmp
#define index __mfwrap_index
#define rindex __mfwrap_rindex
+#define asctime __mfwrap_asctime
+#define ctime __mfwrap_ctime
+#define gmtime __mfwrap_gmtime
+#define localtime __mfwrap_localtime
/* Disable glibc macros. */
#define __NO_STRING_INLINES
More information about the Gcc-patches
mailing list