#ifndef ACL_MALLOC_INCLUDE_H
#define ACL_MALLOC_INCLUDE_H

#ifdef __cplusplus
extern "C" {
#endif

#include "acl_define.h"

/*
 * Memory alignment of memory allocator results.
 * By default we align for doubles.
 */

#ifndef ALIGN_TYPE
# if defined(__hpux) && defined(__ia64)
#  define ALIGN_TYPE	__float80
# elif defined(__ia64__)
#  define ALIGN_TYPE	long double
# else
#  define ALIGN_TYPE	size_t
# endif
#endif

ACL_API int *acl_memory_debug_start(void);
ACL_API void acl_memory_debug_stop(void);
ACL_API void acl_memory_debug_stack(int onoff);
ACL_API void acl_memory_stat(void);
ACL_API void acl_memory_alloc_stat(void);

/**
 * 򿪶̬ڴع
 * @param max_size {size_t} ڴռСλΪֽ
 * @param use_mutex {int} ڴڲǷûǶ̳߳Ӧ
 *   use_mutex Ϊ0ֵ
 */
ACL_API void acl_mempool_open(size_t max_size, int use_mutex);

/**
 * رڴع
 */
ACL_API void acl_mempool_close(void);

/**
 * ڴش򿪺󣬿ͨ˺ڴ״̬
 */
ACL_API void acl_mempool_ctl(int name, ...);
#define	ACL_MEMPOOL_CTL_END         0  /**< ־ */
#define	ACL_MEMPOOL_CTL_MUTEX       1  /**< ڴǷ */
#define	ACL_MEMPOOL_CTL_DISABLE     2  /**< Ƿرڴ */

/**
 * ǰڴѾڴС
 * @return {int} ѾڴС
 */
ACL_API int acl_mempool_total_allocated(void);

/**
 * ǰڴ״̬Ϣ־Ļ
 */
ACL_API void acl_mempool_status(void);

/*---------------- ACLȱʡڴ䡢ͷŵȹӿ -------------------*/

/**
 * õǰڴָһЩ״̬ϢڴʵʴСС
 * @param filename {const char*} øúļΪ
 * @param line {int} øúԴļе
 * @param ptr {void*} ̬ڴⲿַ
 * @param len {size_t*} 洢ڴⲿôС
 * @param real_len {size*} 洢ڴʵʴС(ΪڲһЩֽ)
 */
ACL_API void acl_default_memstat(const char *filename, int line,
        void *ptr, size_t *len, size_t *real_len);

ACL_API void acl_default_meminfo(void);

/**
 * ڴ󱨾ֵ߷ڴСﵽ˱ֵڲԶ
 * ¼־ͬʱöջӡ־Уڲȱֵ 100000000
 * @param len {size_t} 󱨾ֵֵ > 0
 */
ACL_API void acl_default_set_memlimit(size_t len);

/**
 * õǰõڴ󱨾ֵС(ڲȱʡֵ 100000000)
 * @return {size_t}
 */
ACL_API size_t acl_default_get_memlimit(void);

/**
 * ACLȱʡڴӿ, ڴ浫ʼڴ
 * ڱ׼е malloc
 * @param filename {const char*} øúļΪ
 * @param line {int} øúԴļе
 * @param size {size_t} ҪڴС
 * @return {void*} Ŀõַ, ʧܣڲԶcoredump
 *   Ҫ acl_default_free ͷ
 */
ACL_API void *acl_default_malloc(const char *filename, int line, size_t size);

/**
 * ACLȱʡڴӿ, ڴ沢ʼڴΪ0
 * ڱ׼е calloc
 * @param filename {const char*} øúļΪ
 * @param line {int} øúԴļе
 * @param nmemb {size_t} ڴĸ
 * @param size {size_t} ÿڴĴС
 * @return {void*} Ŀõַ, ʧܣڲԶcoredump
 *   Ҫ acl_default_free ͷ
 */
ACL_API void *acl_default_calloc(const char *filename, int line,
		size_t nmemb, size_t size);

/**
 * ACLȱʡڴӿ, ڱ׼ realloc
 * @param filename {const char*} øúļΪ
 * @param line {int} øúԴļе
 * @param ptr {void*} ֮ǰACLڴַ
 * @param size {size_t} ҪڴС
 * @return {void*} Ŀõַ, ʧܣڲԶcoredump
 *   Ҫ acl_default_free ͷ
 */
ACL_API void *acl_default_realloc(const char *filename, int line,
		void *ptr, size_t size);

/**
 * ַڱ׼е strdup
 * @param filename {const char*} øúļΪ
 * @param line {int} øúԴļе
 * @param str {const char*} Դַַ
 * @return {char*} ¸ƵַַҪ acl_default_free ͷ
 */
ACL_API char *acl_default_strdup(const char *filename, int line, const char *str);

/**
 * ַַȣڱ׼е strndup
 * @param filename {const char*} øúļΪ
 * @param line {int} øúԴļе
 * @param str {const char*} Դַַ
 * @param len {size_t} ַ󳤶ֵ
 * @return {char*} ¸ƵַַҪ acl_default_free ͷ
 */
ACL_API char *acl_default_strndup(const char *filename, int line,
		const char *str, size_t len);

/**
 * ڴ
 * @param filename {const char*} øúļΪ
 * @param line {int} øúԴļе
 * @param ptr {const void*} Դڴַ
 * @param len {size_t} Դڴĳ
 * @return {void*} ¸Ƶڴַ 
 */
ACL_API void *acl_default_memdup(const char *filename, int line,
		const void *ptr, size_t len);

/**
 * ͷ acl_devault_xxx ڴ涯̬ڴ
 * @param filename {const char*} øúļΪ
 * @param line {int} øúԴļе
 */
ACL_API void  acl_default_free(const char *filename, int line, void *ptr);

/*----- acl_mymalloc.h ڴӿеĺʹõڴӿ ------*/

/* úӿڼʵǵڴڴķͷŵȹģ
 * ṩ˸߼õⲿʹýӿڣû
 */

ACL_API void *acl_malloc_glue(const char *filename, int line, size_t size);
ACL_API void *acl_calloc_glue(const char *filename, int line, size_t nmemb, size_t size);
ACL_API void *acl_realloc_glue(const char *filename, int line, void *ptr, size_t size);
ACL_API char *acl_strdup_glue(const char *filename, int line, const char *str);
ACL_API char *acl_strndup_glue(const char *filename, int line, const char *str, size_t len);
ACL_API void *acl_memdup_glue(const char *filename, int line, const void *ptr, size_t len);
ACL_API void  acl_free_glue(const char *filename, int line, void *ptr);
ACL_API void  acl_free_fn_glue(void *ptr);

#ifdef __cplusplus
}
#endif

#endif
