mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
Update.
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:
16
ChangeLog
16
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>
|
2001-08-07 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* sysdeps/unix/seekdir.c (seekdir): Set dirp->filepos.
|
* sysdeps/unix/seekdir.c (seekdir): Set dirp->filepos.
|
||||||
|
@ -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];
|
{
|
||||||
else
|
++failed[idx_malloc];
|
||||||
/* Update the allocation data and write out the records if necessary. */
|
return NULL;
|
||||||
update_data (result, len, 0);
|
}
|
||||||
|
|
||||||
|
/* Update the allocation data and write out the records if necessary. */
|
||||||
|
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,24 +370,24 @@ 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
|
|
||||||
{
|
{
|
||||||
/* Record whether the reduction/increase happened in place. */
|
++failed[idx_realloc];
|
||||||
if (real == result)
|
return NULL;
|
||||||
++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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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 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)
|
||||||
{
|
return (*callocp) (n, len);
|
||||||
callocp = (void *(*) (size_t, size_t)) dlsym (RTLD_NEXT, "calloc");
|
|
||||||
|
|
||||||
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];
|
{
|
||||||
else
|
++failed[idx_calloc];
|
||||||
/* Update the allocation data and write out the records if necessary. */
|
return NULL;
|
||||||
update_data (result, size, 0);
|
}
|
||||||
|
|
||||||
/* Return the pointer to the user buffer. */
|
/* Update the allocation data and write out the records if necessary. */
|
||||||
return result ? (void *) (result + 1) : NULL;
|
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;
|
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)
|
||||||
|
@ -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 \
|
||||||
|
@ -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>
|
||||||
|
Reference in New Issue
Block a user