Update.
authorUlrich Drepper <drepper@redhat.com>
Wed, 8 Aug 2001 06:44:42 +0000 (06:44 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 8 Aug 2001 06:44:42 +0000 (06:44 +0000)
2001-08-07  Ulrich Drepper  <drepper@redhat.com>

* sysdeps/ia64/memusage.h (GETTIME): Define using hp-timing.h
funcationality.

* sysdeps/ia64/hp-timing.h (HP_TIMING_NOW): Fix comment.

2001-08-07  Jakub Jelinek  <jakub@redhat.com>

* malloc/memusage.c (initialized): New variable.
(init): If not yet initialized, call me().
(me): Do all dlsym calls here.
(malloc, realloc, calloc, free): If not yet initialized,
call me(). If in the middle of initializing, return NULL or
do nothing.

ChangeLog
malloc/memusage.c
sysdeps/ia64/hp-timing.h
sysdeps/ia64/memusage.h

index 3217df8..27f6ba2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2001-08-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/ia64/memusage.h (GETTIME): Define using hp-timing.h
+       funcationality.
+
+       * sysdeps/ia64/hp-timing.h (HP_TIMING_NOW): Fix comment.
+
+2001-08-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * malloc/memusage.c (initialized): New variable.
+       (init): If not yet initialized, call me().
+       (me): Do all dlsym calls here.
+       (malloc, realloc, calloc, free): If not yet initialized,
+       call me(). If in the middle of initializing, return NULL or
+       do nothing.
+
 2001-08-07  Jakub Jelinek  <jakub@redhat.com>
 
        * sysdeps/unix/seekdir.c (seekdir): Set dirp->filepos.
index 6ae5479..b65440f 100644 (file)
@@ -82,6 +82,7 @@ static size_t buffer_size;
 static int fd = -1;
 
 static int not_me;
+static int initialized;
 extern const char *__progname;
 
 struct entry
@@ -157,15 +158,6 @@ int_handler (int signo)
 }
 
 
-/* Record the initial stack position.  */
-static void
-__attribute__ ((constructor))
-init (void)
-{
-  start_sp = GETSP ();
-}
-
-
 /* Find out whether this is the program we are supposed to profile.
    For this the name in the variable `__progname' must match the one
    given in the environment variable MEMUSAGE_PROG_NAME.  If the variable
@@ -187,6 +179,7 @@ me (void)
 {
   const char *env = getenv ("MEMUSAGE_PROG_NAME");
   size_t prog_len = strlen (__progname);
+
   if (env != NULL)
     {
       /* Check for program name.  */
@@ -199,7 +192,19 @@ me (void)
   /* Only open the file if it's really us.  */
   if (!not_me && fd == -1)
     {
-      const char *outname = getenv ("MEMUSAGE_OUTPUT");
+      const char *outname;
+
+      if (!start_sp)
+       start_sp = GETSP ();
+
+      initialized = -1;
+      mallocp = (void *(*) (size_t)) dlsym (RTLD_NEXT, "malloc");
+      reallocp = (void *(*) (void *, size_t)) dlsym (RTLD_NEXT, "realloc");
+      callocp = (void *(*) (size_t, size_t)) dlsym (RTLD_NEXT, "calloc");
+      freep = (void (*) (void *)) dlsym (RTLD_NEXT, "free");
+      initialized = 1;
+
+      outname = getenv ("MEMUSAGE_OUTPUT");
       if (outname != NULL && outname[0] != '\0'
          && access (outname, R_OK | W_OK) == 0)
        {
@@ -253,6 +258,17 @@ me (void)
 }
 
 
+/* Record the initial stack position.  */
+static void
+__attribute__ ((constructor))
+init (void)
+{
+  start_sp = GETSP ();
+  if (! initialized)
+    me ();
+}
+
+
 /* `malloc' replacement.  We keep track of the memory usage if this is the
    correct program.  */
 void *
@@ -261,10 +277,11 @@ malloc (size_t len)
   struct header *result = NULL;
 
   /* Determine real implementation if not already happened.  */
-  if (mallocp == NULL)
+  if (__builtin_expect (initialized <= 0, 0))
     {
+      if (initialized == -1)
+       return NULL;
       me ();
-      mallocp = (void *(*) (size_t)) dlsym (RTLD_NEXT, "malloc");
     }
 
   /* If this is not the correct program just use the normal function.  */
@@ -287,15 +304,17 @@ malloc (size_t len)
 
   /* Do the real work.  */
   result = (struct header *) (*mallocp) (len + sizeof (struct header));
-
   if (result == NULL)
-    ++failed[idx_malloc];
-  else
-    /* Update the allocation data and write out the records if necessary.  */
-    update_data (result, len, 0);
+    {
+      ++failed[idx_malloc];
+      return NULL;
+    }
+
+  /* Update the allocation data and write out the records if necessary.  */
+  update_data (result, len, 0);
 
   /* Return the pointer to the user buffer.  */
-  return result ? (void *) (result + 1) : NULL;
+  return (void *) (result + 1);
 }
 
 
@@ -309,10 +328,11 @@ realloc (void *old, size_t len)
   size_t old_len;
 
   /* Determine real implementation if not already happened.  */
-  if (reallocp == NULL)
+  if (__builtin_expect (initialized <= 0, 0))
     {
+      if (initialized == -1)
+       return NULL;
       me ();
-      reallocp = (void *(*) (void *, size_t)) dlsym (RTLD_NEXT, "realloc");
     }
 
   /* If this is not the correct program just use the normal function.  */
@@ -350,24 +370,24 @@ realloc (void *old, size_t len)
 
   /* Do the real work.  */
   result = (struct header *) (*reallocp) (real, len + sizeof (struct header));
-
   if (result == NULL)
-    ++failed[idx_realloc];
-  else
     {
-      /* Record whether the reduction/increase happened in place.  */
-      if (real == result)
-        ++inplace;
-      /* Was the buffer increased?  */
-      if (old_len > len)
-       ++decreasing;
-
-      /* Update the allocation data and write out the records if necessary.  */
-      update_data (result, len, old_len);
+      ++failed[idx_realloc];
+      return NULL;
     }
 
+  /* Record whether the reduction/increase happened in place.  */
+  if (real == result)
+    ++inplace;
+  /* Was the buffer increased?  */
+  if (old_len > len)
+    ++decreasing;
+
+  /* Update the allocation data and write out the records if necessary.  */
+  update_data (result, len, old_len);
+
   /* Return the pointer to the user buffer.  */
-  return result ? (void *) (result + 1) : NULL;
+  return (void *) (result + 1);
 }
 
 
@@ -379,23 +399,17 @@ calloc (size_t n, size_t len)
   struct header *result;
   size_t size = n * len;
 
-  /* Determine real implementation if not already happened.  We are
-     searching for the `malloc' implementation since it is not always
-     efficiently possible to use `calloc' because we have to add a bit
-     room to the allocation to put the header in.  */
-  if (mallocp == NULL)
+  /* Determine real implementation if not already happened.  */
+  if (__builtin_expect (initialized <= 0, 0))
     {
+      if (initialized == -1)
+       return NULL;
       me ();
-      mallocp = (void *(*) (size_t)) dlsym (RTLD_NEXT, "malloc");
     }
 
   /* If this is not the correct program just use the normal function.  */
   if (not_me)
-    {
-      callocp = (void *(*) (size_t, size_t)) dlsym (RTLD_NEXT, "calloc");
-
-      return (*callocp) (n, len);
-    }
+    return (*callocp) (n, len);
 
   /* Keep track of number of calls.  */
   ++calls[idx_calloc];
@@ -413,17 +427,17 @@ calloc (size_t n, size_t len)
 
   /* Do the real work.  */
   result = (struct header *) (*mallocp) (size + sizeof (struct header));
-  if (result != NULL)
-    memset (result + 1, '\0', size);
-
   if (result == NULL)
-    ++failed[idx_calloc];
-  else
-    /* Update the allocation data and write out the records if necessary.  */
-    update_data (result, size, 0);
+    {
+      ++failed[idx_calloc];
+      return NULL;
+    }
 
-  /* Return the pointer to the user buffer.  */
-  return result ? (void *) (result + 1) : NULL;
+  /* Update the allocation data and write out the records if necessary.  */
+  update_data (result, size, 0);
+
+  /* Do what `calloc' would have done and return the buffer to the caller.  */
+  return memset (result + 1, '\0', size);
 }
 
 
@@ -434,18 +448,12 @@ free (void *ptr)
 {
   struct header *real;
 
-  /* `free (NULL)' has no effect.  */
-  if (ptr == NULL)
-    {
-      ++calls[idx_free];
-      return;
-    }
-
   /* Determine real implementation if not already happened.  */
-  if (freep == NULL)
+  if (__builtin_expect (initialized <= 0, 0))
     {
+      if (initialized == -1)
+       return;
       me ();
-      freep = (void (*) (void *)) dlsym (RTLD_NEXT, "free");
     }
 
   /* If this is not the correct program just use the normal function.  */
@@ -455,6 +463,13 @@ free (void *ptr)
       return;
     }
 
+  /* `free (NULL)' has no effect.  */
+  if (ptr == NULL)
+    {
+      ++calls[idx_free];
+      return;
+    }
+
   /* Determine the pointer to the header.  */
   real = ((struct header *) ptr) - 1;
   if (real->magic != MAGIC)
index ed1dc60..da2cd8e 100644 (file)
@@ -92,11 +92,7 @@ extern hp_timing_t __libc_hp_timing_overhead;
    processor implementation.  */
 #define REPEAT_READ(val) __builtin_expect ((int) val == -1, 0)
 
-/* That's quite simple.  Use the `rdtsc' instruction.  Note that the value
-   might not be 100% accurate since there might be some more instructions
-   running in this moment.  This could be changed by using a barrier like
-   'cpuid' right before the `rdtsc' instruciton.  But we are not interested
-   in accurate clock cycles here so we don't do this.  */
+/* That's quite simple.  Use the `ar.itc' instruction.  */
 #define HP_TIMING_NOW(Var) \
   ({ unsigned long int __itc;                                                \
      do                                                                              \
index 5ca0782..5f395b8 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <hp-timing.h>
 
 #define GETSP() ({ register uintptr_t stack_ptr asm ("%r12"); stack_ptr; })
+#define GETTIME(low, high) \
+  {                                                                          \
+    hp_timing_t __now;                                                       \
+    HP_TIMING_NOW (__now);                                                   \
+    low = __now & 0xffffffff;                                                \
+    high = __now >> 32;                                                              \
+  }
 
 #include <sysdeps/generic/memusage.h>