/*
 * kmp_wrapper_malloc.h -- Wrappers for memory allocation routines
 *                         (malloc(), free(), and others).
 * $Revision: 43084 $
 * $Date: 2014-04-15 09:15:14 -0500 (Tue, 15 Apr 2014) $
 */


//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//


#ifndef KMP_WRAPPER_MALLOC_H
#define KMP_WRAPPER_MALLOC_H

/*
    This header serves for 3 purposes:

        1. Declaring standard memory allocation rourines in OS-independent way.
        2. Passing source location info through memory allocation wrappers.
        3. Enabling native memory debugging capabilities.


    1. Declaring standard memory allocation rourines in OS-independent way.
    -----------------------------------------------------------------------

    On Linux* OS, alloca() function is declared in <alloca.h> header, while on Windows* OS there is no
    <alloca.h> header, function _alloca() (note underscore!) is declared in <malloc.h>. This header
    eliminates these differences, so client code incluiding "kmp_wrapper_malloc.h" can rely on
    following routines:

        malloc
        calloc
        realloc
        free
        alloca

    in OS-independent way. It also enables memory tracking capabilities in debug build. (Currently
    it is available only on Windows* OS.)


    2. Passing source location info through memory allocation wrappers.
    -------------------------------------------------------------------

    Some tools may help debugging memory errors, for example, report memory leaks. However, memory
    allocation wrappers may hinder source location.

    For example:

        void * aligned_malloc( int size ) {
            void * ptr = malloc( size ); // All the memory leaks will be reported at this line.
            // some adjustments...
            return ptr;
        };

        ptr = aligned_malloc( size );    // Memory leak will *not* be detected here. :-(

    To overcome the problem, information about original source location should be passed through all
    the memory allocation wrappers, for example:

        void * aligned_malloc( int size, char const * file, int line ) {
            void * ptr = _malloc_dbg( size, file, line );
            // some adjustments...
            return ptr;
        };

        void * ptr = aligned_malloc( size, __FILE__, __LINE__ );

    This is a good idea for debug, but passing additional arguments impacts performance. Disabling
    extra arguments in release version of the software introduces too many conditional compilation,
    which makes code unreadable. This header defines few macros and functions facilitating it:

        void * _aligned_malloc( int size KMP_SRC_LOC_DECL ) {
            void * ptr = malloc_src_loc( size KMP_SRC_LOC_PARM );
            // some adjustments...
            return ptr;
        };
        #define aligned_malloc( size ) _aligned_malloc( (size) KMP_SRC_LOC_CURR )
            // Use macro instead of direct call to function.

        void * ptr = aligned_malloc( size );  // Bingo! Memory leak will be reported at this line.


    3. Enabling native memory debugging capabilities.
    -------------------------------------------------

    Some platforms may offer memory debugging capabilities. For example, debug version of Microsoft
    RTL tracks all memory allocations and can report memory leaks. This header enables this, and
    makes report more useful (see "Passing source location info through memory allocation
    wrappers").

*/

#include <stdlib.h>

#include "kmp_os.h"

// Include alloca() declaration.
#if KMP_OS_WINDOWS
    #include <malloc.h>        // Windows* OS: _alloca() declared in "malloc.h".
    #define alloca _alloca     // Allow to use alloca() with no underscore.
#elif KMP_OS_FREEBSD
    // Declared in "stdlib.h".
#elif KMP_OS_UNIX
    #include <alloca.h>        // Linux* OS and OS X*: alloc() declared in "alloca".
#else
    #error Unknown or unsupported OS.
#endif

/*
    KMP_SRC_LOC_DECL -- Declaring source location paramemters, to be used in function declaration.
    KMP_SRC_LOC_PARM -- Source location paramemters, to be used to pass parameters to underlying
        levels.
    KMP_SRC_LOC_CURR -- Source location arguments describing current location, to be used at
        top-level.

    Typical usage:

        void * _aligned_malloc( int size KMP_SRC_LOC_DECL ) {
            // Note: Comma is missed before KMP_SRC_LOC_DECL.
            KE_TRACE( 25, ( "called from %s:%d\n", KMP_SRC_LOC_PARM ) );
            ...
        }
        #define aligned_malloc( size ) _aligned_malloc( (size) KMP_SRC_LOC_CURR )
            // Use macro instead of direct call to function -- macro passes info about current
            // source location to the func.
*/
#if KMP_DEBUG
    #define KMP_SRC_LOC_DECL    , char const * _file_, int _line_
    #define KMP_SRC_LOC_PARM    , _file_, _line_
    #define KMP_SRC_LOC_CURR    , __FILE__, __LINE__
#else
    #define KMP_SRC_LOC_DECL
    #define KMP_SRC_LOC_PARM
    #define KMP_SRC_LOC_CURR
#endif // KMP_DEBUG

/*
    malloc_src_loc() and free_src_loc() are pseudo-functions (really macros) with accepts extra
    arguments (source location info) in debug mode. They should be used in place of malloc() and
    free(), this allows enabling native memory debugging capabilities (if any).

    Typical usage:

        ptr = malloc_src_loc( size KMP_SRC_LOC_PARM );
            // Inside memory allocation wrapper, or
        ptr = malloc_src_loc( size KMP_SRC_LOC_CURR );
            // Outside of memory allocation wrapper.


*/
#define malloc_src_loc( args )    _malloc_src_loc( args )
#define free_src_loc(   args )    _free_src_loc(   args )
    /*
        Depending on build mode (debug or release), malloc_src_loc is declared with 1 or 3
        parameters, but calls to malloc_src_loc() are always the same:

            ... malloc_src_loc( size KMP_SRC_LOC_PARM ); // or KMP_SRC_LOC_CURR

        Compiler issues warning/error "too few arguments in macro invocation". Declaring two
        macroses, malloc_src_loc() and _malloc_src_loc() overcomes the problem.
    */

#if KMP_DEBUG

    #if KMP_OS_WINDOWS && _DEBUG
        // KMP_DEBUG != _DEBUG. MS debug RTL is available only if _DEBUG is defined.

        // Windows* OS has native memory debugging capabilities. Enable them.

        #include <crtdbg.h>

        #define KMP_MEM_BLOCK           _CLIENT_BLOCK
        #define malloc( size )          _malloc_dbg( (size), KMP_MEM_BLOCK, __FILE__, __LINE__ )
        #define calloc( num, size )     _calloc_dbg( (num), (size), KMP_MEM_BLOCK, __FILE__, __LINE__ )
        #define realloc( ptr, size )    _realloc_dbg( (ptr), (size), KMP_MEM_BLOCK, __FILE__, __LINE__ )
        #define free( ptr )             _free_dbg( (ptr), KMP_MEM_BLOCK )

        #define _malloc_src_loc( size, file, line )  _malloc_dbg( (size), KMP_MEM_BLOCK, (file), (line) )
        #define _free_src_loc(    ptr, file, line )  _free_dbg(   (ptr),  KMP_MEM_BLOCK                 )

    #else

        // Linux* OS, OS X*, or non-debug Windows* OS.

        #define _malloc_src_loc( size, file, line )    malloc( (size) )
        #define _free_src_loc( ptr, file, line )       free( (ptr) )

    #endif

#else

    // In release build malloc_src_loc() and free_src_loc() do not have extra parameters.
    #define _malloc_src_loc( size )    malloc( (size) )
    #define _free_src_loc( ptr )       free( (ptr) )

#endif // KMP_DEBUG

#endif // KMP_WRAPPER_MALLOC_H

// end of file //
