/*
 * kmp_wrapper_malloc.h -- Wrappers for memory allocation routines
 *                         (malloc(), free(), and others).
 */


//===----------------------------------------------------------------------===//
//
//                     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 || KMP_OS_NETBSD
    // 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 //
