PAPI  5.0.1.0
papi_memory.c File Reference
Include dependency graph for papi_memory.c:

Go to the source code of this file.

Defines

#define IN_MEM_FILE
#define MEM_PROLOG   (2*sizeof(void *))

Functions

static pmem_tget_mem_ptr (void *ptr)
static pmem_tinit_mem_ptr (void *, int, char *, int)
static void insert_mem_ptr (pmem_t *)
static void remove_mem_ptr (pmem_t *)
static int set_epilog (pmem_t *mem_ptr)
void * _papi_realloc (char *file, int line, void *ptr, size_t size)
void * _papi_calloc (char *file, int line, size_t nmemb, size_t size)
void * _papi_malloc (char *file, int line, size_t size)
char * _papi_strdup (char *file, int line, const char *s)
int _papi_valid_free (char *file, int line, void *ptr)
void _papi_free (char *file, int line, void *ptr)
void _papi_mem_print_info (void *ptr)
void _papi_mem_print_stats ()
int _papi_mem_overhead (int type)
void _papi_mem_cleanup_all ()
int _papi_mem_check_all_overflow ()

Variables

static pmem_tmem_head = NULL

Detailed Description

Author:
Kevin London london@cs.utk.edu PAPI memory allocation provides for checking and maintenance of all memory allocated through this interface. Implemented as a series of wrappers around standard C memory allocation routines, _papi_malloc and associated functions add a prolog and optional epilog to each malloc'd pointer. The prolog, sized to preserve memory alignment, contains a pointer to a linked list of pmem_t structures that describe every block of memory allocated through these calls. The optional epilog is enabled if DEBUG is defined, and contains a distinctive pattern that allows checking for pointer overflow.

Definition in file papi_memory.c.


Define Documentation

#define IN_MEM_FILE

Definition at line 16 of file papi_memory.c.

#define MEM_PROLOG   (2*sizeof(void *))

Define the amount of extra memory at the beginning of the alloc'd pointer. This is usually the size of a pointer, but in some cases needs to be bigger to preserve data alignment.

Definition at line 31 of file papi_memory.c.


Function Documentation

void* _papi_calloc ( char *  file,
int  line,
size_t  nmemb,
size_t  size 
)

Definition at line 113 of file papi_memory.c.

{
    void *ptr = _papi_malloc( file, line, size * nmemb );

    if ( !ptr )
        return ( NULL );
    memset( ptr, 0, size * nmemb );
    return ( ptr );
}

Here is the call graph for this function:

void _papi_free ( char *  file,
int  line,
void *  ptr 
)

Frees up the ptr

< Used with setting up array

< Used with setting up array

Definition at line 226 of file papi_memory.c.

{
    pmem_t *mem_ptr = get_mem_ptr( ptr );

    if ( !mem_ptr ) {
        ( void ) file;
        ( void ) line;
        return;
    }

    MEMDBG( "%p: Freeing %d bytes from File: %s  Line: %d\n", mem_ptr->ptr,
            mem_ptr->size, file, line );

    _papi_hwi_lock( MEMORY_LOCK );
    remove_mem_ptr( mem_ptr );
    _papi_mem_check_all_overflow(  );
    _papi_hwi_unlock( MEMORY_LOCK );
}

Here is the call graph for this function:

void* _papi_malloc ( char *  file,
int  line,
size_t  size 
)

< Used with setting up array

< Used with setting up array

Definition at line 124 of file papi_memory.c.

{
    void *ptr;
    void **tmp;
    pmem_t *mem_ptr;
    size_t nsize = size + MEM_PROLOG;

#ifdef DEBUG
    nsize += MEM_EPILOG;
#endif

    if ( size == 0 ) {
        MEMDBG( "Attempting to allocate %lu bytes from File: %s  Line: %d\n",
                ( unsigned long ) size, file, line );
        return ( NULL );
    }

    ptr = ( void * ) malloc( nsize );

    if ( !ptr )
        return ( NULL );
    else {
        if ( ( mem_ptr =
               init_mem_ptr( ( char * ) ptr + MEM_PROLOG, ( int ) size, file,
                             line ) ) == NULL ) {
            free( ptr );
            return ( NULL );
        }
        tmp = ptr;
        *tmp = mem_ptr;
        ptr = mem_ptr->ptr;
        mem_ptr->ptr = ptr;
        _papi_hwi_lock( MEMORY_LOCK );
        insert_mem_ptr( mem_ptr );
        set_epilog( mem_ptr );
        _papi_hwi_unlock( MEMORY_LOCK );

        MEMDBG( "%p: Allocated %lu bytes from File: %s  Line: %d\n",
                mem_ptr->ptr, ( unsigned long ) size, file, line );
        return ( ptr );
    }
    return ( NULL );
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 470 of file papi_memory.c.

{
    int fnd = 0;
#ifdef DEBUG
    pmem_t *tmp;

    for ( tmp = mem_head; tmp; tmp = tmp->next ) {
        if ( _papi_mem_check_buf_overflow( tmp ) )
            fnd++;
    }

    if ( fnd ) {
        LEAKDBG( "%d Total Buffer overflows detected!\n", fnd );
    }
#endif
    return ( fnd );
}

Here is the caller graph for this function:

Clean all memory up and print out memory leak information to stderr

< Used with setting up array

< Used with setting up array

Definition at line 303 of file papi_memory.c.

{
    pmem_t *ptr = NULL, *tmp = NULL;
#ifdef DEBUG
    int cnt = 0;
#endif

    _papi_hwi_lock( MEMORY_LOCK );
    _papi_mem_check_all_overflow(  );

    for ( ptr = mem_head; ptr; ptr = tmp ) {
        tmp = ptr->next;
#ifdef DEBUG
        LEAKDBG( "MEMORY LEAK: %p of %d bytes, from File: %s Line: %d\n",
                 ptr->ptr, ptr->size, ptr->file, ptr->line );
        cnt += ptr->size;
#endif

        remove_mem_ptr( ptr );
    }
    _papi_hwi_unlock( MEMORY_LOCK );
#ifdef DEBUG
    if ( 0 != cnt ) { 
        LEAKDBG( "TOTAL MEMORY LEAK: %d bytes.\n", cnt );
    }
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_mem_overhead ( int  type)

Return the amount of memory overhead of the PAPI library and the memory system PAPI_MEM_LIB_OVERHEAD is the library overhead PAPI_MEM_OVERHEAD is the memory overhead They both can be | together This only includes "malloc'd memory"

< Used with setting up array

< Used with setting up array

Definition at line 280 of file papi_memory.c.

{
    pmem_t *ptr = NULL;
    int size = 0;

    _papi_hwi_lock( MEMORY_LOCK );
    for ( ptr = mem_head; ptr; ptr = ptr->next ) {
        if ( type & PAPI_MEM_LIB_OVERHEAD )
            size += ptr->size;
        if ( type & PAPI_MEM_OVERHEAD ) {
            size += ( int ) sizeof ( pmem_t );
            size += ( int ) MEM_PROLOG;
#ifdef DEBUG
            size += ( int ) MEM_EPILOG;
#endif
        }
    }
    _papi_hwi_unlock( MEMORY_LOCK );
    return size;
}

Here is the call graph for this function:

void _papi_mem_print_info ( void *  ptr)

Print information about the memory including file and location it came from

Definition at line 247 of file papi_memory.c.

{
    pmem_t *mem_ptr = get_mem_ptr( ptr );

#ifdef DEBUG
    fprintf( stderr, "%p: Allocated %d bytes from File: %s  Line: %d\n", ptr,
             mem_ptr->size, mem_ptr->file, mem_ptr->line );
#else
    fprintf( stderr, "%p: Allocated %d bytes\n", ptr, mem_ptr->size );
#endif
    return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Print out all memory information

< Used with setting up array

< Used with setting up array

Definition at line 262 of file papi_memory.c.

{
    pmem_t *tmp = NULL;

    _papi_hwi_lock( MEMORY_LOCK );
    for ( tmp = mem_head; tmp; tmp = tmp->next ) {
        _papi_mem_print_info( tmp->ptr );
    }
    _papi_hwi_unlock( MEMORY_LOCK );
}

Here is the call graph for this function:

void* _papi_realloc ( char *  file,
int  line,
void *  ptr,
size_t  size 
)

_papi_realloc -- given a pointer returned by _papi_malloc, returns a pointer to the related pmem_t structure describing this pointer. Checks for NULL pointers and returns NULL if error.

Definition at line 77 of file papi_memory.c.

{
    size_t nsize = size + MEM_PROLOG;
    pmem_t *mem_ptr;
    void *nptr;

#ifdef DEBUG
    nsize += MEM_EPILOG;
    _papi_hwi_lock( MEMORY_LOCK );
    _papi_mem_check_all_overflow(  );
#endif

    if ( !ptr )
        return ( _papi_malloc( file, line, size ) );

    mem_ptr = get_mem_ptr( ptr );
    nptr = ( pmem_t * ) realloc( ( ( char * ) ptr - MEM_PROLOG ), nsize );

    if ( !nptr )
        return ( NULL );

    mem_ptr->size = ( int ) size;
    mem_ptr->ptr = ( char * ) nptr + MEM_PROLOG;
#ifdef DEBUG
    strncpy( mem_ptr->file, file, DEBUG_FILE_LEN );
    mem_ptr->file[DEBUG_FILE_LEN - 1] = '\0';
    mem_ptr->line = line;
    set_epilog( mem_ptr );
    _papi_hwi_unlock( MEMORY_LOCK );
#endif
    MEMDBG( "%p: Re-allocated: %lu bytes from File: %s  Line: %d\n",
            mem_ptr->ptr, ( unsigned long ) size, file, line );
    return ( mem_ptr->ptr );
}

Here is the call graph for this function:

char* _papi_strdup ( char *  file,
int  line,
const char *  s 
)

Definition at line 169 of file papi_memory.c.

{
    size_t size;
    char *ptr;

    if ( !s )
        return ( NULL );

    /* String Length +1 for \0 */
    size = strlen( s ) + 1;
    ptr = ( char * ) _papi_malloc( file, line, size );

    if ( !ptr )
        return ( NULL );

    memcpy( ptr, s, size );
    return ( ptr );
}

Here is the call graph for this function:

int _papi_valid_free ( char *  file,
int  line,
void *  ptr 
)

Only frees the memory if PAPI malloced it returns 1 if pointer was valid; 0 if not

< Used with setting up array

< Used with setting up array

Definition at line 191 of file papi_memory.c.

{
    pmem_t *tmp;
    int valid = 0;

    if ( !ptr ) {
        ( void ) file;
        ( void ) line;
        return ( 0 );
    }

    _papi_hwi_lock( MEMORY_LOCK );

    for ( tmp = mem_head; tmp; tmp = tmp->next ) {
        if ( ptr == tmp->ptr ) {
            pmem_t *mem_ptr = get_mem_ptr( ptr );

            if ( mem_ptr ) {
                MEMDBG( "%p: Freeing %d bytes from File: %s  Line: %d\n",
                        mem_ptr->ptr, mem_ptr->size, file, line );
                remove_mem_ptr( mem_ptr );
                _papi_mem_check_all_overflow(  );
            }

            valid = 1;
            break;
        }
    }

    _papi_hwi_unlock( MEMORY_LOCK );
    return ( valid );
}

Here is the call graph for this function:

static pmem_t * get_mem_ptr ( void *  ptr) [static]

Definition at line 344 of file papi_memory.c.

{
    pmem_t **tmp_ptr = ( pmem_t ** ) ( ( char * ) ptr - MEM_PROLOG );
    pmem_t *mem_ptr;

    if ( !tmp_ptr || !ptr )
        return ( NULL );

    mem_ptr = *tmp_ptr;
    return ( mem_ptr );
}

Here is the caller graph for this function:

pmem_t * init_mem_ptr ( void *  ptr,
int  size,
char *  file,
int  line 
) [static]

Definition at line 358 of file papi_memory.c.

{
    pmem_t *mem_ptr = NULL;
    if ( ( mem_ptr = ( pmem_t * ) malloc( sizeof ( pmem_t ) ) ) == NULL )
        return ( NULL );

    mem_ptr->ptr = ptr;
    mem_ptr->size = size;
    mem_ptr->next = NULL;
    mem_ptr->prev = NULL;
#ifdef DEBUG
    strncpy( mem_ptr->file, file, DEBUG_FILE_LEN );
    mem_ptr->file[DEBUG_FILE_LEN - 1] = '\0';
    mem_ptr->line = line;
#else
    ( void ) file;           /*unused */
    ( void ) line;           /*unused */
#endif
    return ( mem_ptr );
}

Here is the caller graph for this function:

static void insert_mem_ptr ( pmem_t ptr) [static]

Definition at line 383 of file papi_memory.c.

{
    if ( !ptr )
        return;

    if ( !mem_head ) {
        mem_head = ptr;
        ptr->next = NULL;
        ptr->prev = NULL;
    } else {
        mem_head->prev = ptr;
        ptr->next = mem_head;
        mem_head = ptr;
    }
    return;
}

Here is the caller graph for this function:

static void remove_mem_ptr ( pmem_t ptr) [static]

Definition at line 405 of file papi_memory.c.

{
    if ( !ptr )
        return;

    if ( ptr->prev )
        ptr->prev->next = ptr->next;
    if ( ptr->next )
        ptr->next->prev = ptr->prev;
    if ( ptr == mem_head )
        mem_head = ptr->next;
    free( ptr );
}

Here is the caller graph for this function:

static int set_epilog ( pmem_t mem_ptr) [static]

Definition at line 420 of file papi_memory.c.

{
#ifdef DEBUG
    char *chptr = ( char * ) mem_ptr->ptr + mem_ptr->size;
    *chptr++ = MEM_EPILOG_1;
    *chptr++ = MEM_EPILOG_2;
    *chptr++ = MEM_EPILOG_3;
    *chptr++ = MEM_EPILOG_4;
    return ( _papi_mem_check_all_overflow(  ) );
#else
    ( void ) mem_ptr;        /*unused */
#endif
    return ( 0 );
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

pmem_t* mem_head = NULL [static]

Definition at line 46 of file papi_memory.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines