1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00
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.
This commit is contained in:
Ulrich Drepper
2001-08-08 06:44:42 +00:00
parent d1a5466da8
commit b412350783
4 changed files with 103 additions and 68 deletions

View File

@ -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> 2001-08-07 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/seekdir.c (seekdir): Set dirp->filepos. * sysdeps/unix/seekdir.c (seekdir): Set dirp->filepos.

View File

@ -82,6 +82,7 @@ static size_t buffer_size;
static int fd = -1; static int fd = -1;
static int not_me; static int not_me;
static int initialized;
extern const char *__progname; extern const char *__progname;
struct entry 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. /* Find out whether this is the program we are supposed to profile.
For this the name in the variable `__progname' must match the one For this the name in the variable `__progname' must match the one
given in the environment variable MEMUSAGE_PROG_NAME. If the variable given in the environment variable MEMUSAGE_PROG_NAME. If the variable
@ -187,6 +179,7 @@ me (void)
{ {
const char *env = getenv ("MEMUSAGE_PROG_NAME"); const char *env = getenv ("MEMUSAGE_PROG_NAME");
size_t prog_len = strlen (__progname); size_t prog_len = strlen (__progname);
if (env != NULL) if (env != NULL)
{ {
/* Check for program name. */ /* Check for program name. */
@ -199,7 +192,19 @@ me (void)
/* Only open the file if it's really us. */ /* Only open the file if it's really us. */
if (!not_me && fd == -1) 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' if (outname != NULL && outname[0] != '\0'
&& access (outname, R_OK | W_OK) == 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 /* `malloc' replacement. We keep track of the memory usage if this is the
correct program. */ correct program. */
void * void *
@ -261,10 +277,11 @@ malloc (size_t len)
struct header *result = NULL; struct header *result = NULL;
/* Determine real implementation if not already happened. */ /* Determine real implementation if not already happened. */
if (mallocp == NULL) if (__builtin_expect (initialized <= 0, 0))
{ {
if (initialized == -1)
return NULL;
me (); me ();
mallocp = (void *(*) (size_t)) dlsym (RTLD_NEXT, "malloc");
} }
/* If this is not the correct program just use the normal function. */ /* If this is not the correct program just use the normal function. */
@ -287,15 +304,17 @@ malloc (size_t len)
/* Do the real work. */ /* Do the real work. */
result = (struct header *) (*mallocp) (len + sizeof (struct header)); result = (struct header *) (*mallocp) (len + sizeof (struct header));
if (result == NULL) if (result == NULL)
{
++failed[idx_malloc]; ++failed[idx_malloc];
else return NULL;
}
/* Update the allocation data and write out the records if necessary. */ /* Update the allocation data and write out the records if necessary. */
update_data (result, len, 0); update_data (result, len, 0);
/* Return the pointer to the user buffer. */ /* 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; size_t old_len;
/* Determine real implementation if not already happened. */ /* Determine real implementation if not already happened. */
if (reallocp == NULL) if (__builtin_expect (initialized <= 0, 0))
{ {
if (initialized == -1)
return NULL;
me (); me ();
reallocp = (void *(*) (void *, size_t)) dlsym (RTLD_NEXT, "realloc");
} }
/* If this is not the correct program just use the normal function. */ /* If this is not the correct program just use the normal function. */
@ -350,11 +370,12 @@ realloc (void *old, size_t len)
/* Do the real work. */ /* Do the real work. */
result = (struct header *) (*reallocp) (real, len + sizeof (struct header)); result = (struct header *) (*reallocp) (real, len + sizeof (struct header));
if (result == NULL) if (result == NULL)
++failed[idx_realloc];
else
{ {
++failed[idx_realloc];
return NULL;
}
/* Record whether the reduction/increase happened in place. */ /* Record whether the reduction/increase happened in place. */
if (real == result) if (real == result)
++inplace; ++inplace;
@ -364,10 +385,9 @@ realloc (void *old, size_t len)
/* Update the allocation data and write out the records if necessary. */ /* Update the allocation data and write out the records if necessary. */
update_data (result, len, old_len); update_data (result, len, old_len);
}
/* Return the pointer to the user buffer. */ /* 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; struct header *result;
size_t size = n * len; size_t size = n * len;
/* Determine real implementation if not already happened. We are /* Determine real implementation if not already happened. */
searching for the `malloc' implementation since it is not always if (__builtin_expect (initialized <= 0, 0))
efficiently possible to use `calloc' because we have to add a bit
room to the allocation to put the header in. */
if (mallocp == NULL)
{ {
if (initialized == -1)
return NULL;
me (); me ();
mallocp = (void *(*) (size_t)) dlsym (RTLD_NEXT, "malloc");
} }
/* If this is not the correct program just use the normal function. */ /* If this is not the correct program just use the normal function. */
if (not_me) 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. */ /* Keep track of number of calls. */
++calls[idx_calloc]; ++calls[idx_calloc];
@ -413,17 +427,17 @@ calloc (size_t n, size_t len)
/* Do the real work. */ /* Do the real work. */
result = (struct header *) (*mallocp) (size + sizeof (struct header)); result = (struct header *) (*mallocp) (size + sizeof (struct header));
if (result != NULL)
memset (result + 1, '\0', size);
if (result == NULL) if (result == NULL)
{
++failed[idx_calloc]; ++failed[idx_calloc];
else return NULL;
}
/* Update the allocation data and write out the records if necessary. */ /* Update the allocation data and write out the records if necessary. */
update_data (result, size, 0); update_data (result, size, 0);
/* Return the pointer to the user buffer. */ /* Do what `calloc' would have done and return the buffer to the caller. */
return result ? (void *) (result + 1) : NULL; return memset (result + 1, '\0', size);
} }
@ -434,18 +448,12 @@ free (void *ptr)
{ {
struct header *real; struct header *real;
/* `free (NULL)' has no effect. */
if (ptr == NULL)
{
++calls[idx_free];
return;
}
/* Determine real implementation if not already happened. */ /* Determine real implementation if not already happened. */
if (freep == NULL) if (__builtin_expect (initialized <= 0, 0))
{ {
if (initialized == -1)
return;
me (); me ();
freep = (void (*) (void *)) dlsym (RTLD_NEXT, "free");
} }
/* If this is not the correct program just use the normal function. */ /* If this is not the correct program just use the normal function. */
@ -455,6 +463,13 @@ free (void *ptr)
return; return;
} }
/* `free (NULL)' has no effect. */
if (ptr == NULL)
{
++calls[idx_free];
return;
}
/* Determine the pointer to the header. */ /* Determine the pointer to the header. */
real = ((struct header *) ptr) - 1; real = ((struct header *) ptr) - 1;
if (real->magic != MAGIC) if (real->magic != MAGIC)

View File

@ -92,11 +92,7 @@ extern hp_timing_t __libc_hp_timing_overhead;
processor implementation. */ processor implementation. */
#define REPEAT_READ(val) __builtin_expect ((int) val == -1, 0) #define REPEAT_READ(val) __builtin_expect ((int) val == -1, 0)
/* That's quite simple. Use the `rdtsc' instruction. Note that the value /* That's quite simple. Use the `ar.itc' instruction. */
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. */
#define HP_TIMING_NOW(Var) \ #define HP_TIMING_NOW(Var) \
({ unsigned long int __itc; \ ({ unsigned long int __itc; \
do \ do \

View 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -16,7 +16,15 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */ 02111-1307 USA. */
#include <hp-timing.h>
#define GETSP() ({ register uintptr_t stack_ptr asm ("%r12"); stack_ptr; }) #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> #include <sysdeps/generic/memusage.h>