/* vim: ts=4 sw=4 sts=4 ff=unix fenc=utf-8 :
 * =====================================================================
 *  sc_mmgr.h
 *  Copyright (c)  2003 - 2011  sys0tem
 *  LICENSE :
 *	LGPL (GNU Lesser General Public License - Version 3,29 June 2007)
 *	http://www.gnu.org/copyleft/lesser.html
 *	or
 *	EPL (Eclipse Public License - v1.0)
 *	http://www.eclipse.org/legal/epl-v10.html
 * =====================================================================
 */
#ifndef __SC_MMGR_H__
#define __SC_MMGR_H__


#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif


/* メモリ管理用 1 byte 型 */
typedef unsigned char sc_unit_t;

typedef enum {
	SC_MMgr_ALLOCATED = 0x01234567,
	SC_MMgr_DELETED   = 0xFEDCBA98
} SC_MMgrMark;


/**
 * 管理メモリブロック。
 *
 * [注意]
 * 可変長配列のように振舞う char _data[1] という表現は、
 * 厳密には ANSI C言語には準拠していない。・・・が、
 * 世の中に知られているすべてのコンパイラの実装で、
 * この方法は移植性が高い。
 *
 * 管理サイズ毎に構造体を作成する。または、malloc (or calloc) を
 * 複数回実行する実装方法があるが、極端に速度が遅くなるなどの
 * 問題があるため、本実装としている。
 */
typedef struct SC_MMgr_ {
	const char*      file;		/*< 確保箇所 (ソースファイル名)	*/
	int              line;		/*< 確保箇所 (行番号)			*/
	size_t           size;		/*< 確保メモリサイズ			*/
	int              _mark;		/*< 確保メモリ状態				*/
	struct SC_MMgr_* _prev;		/*< 前の管理メモリへのポインタ	*/
	struct SC_MMgr_* _next;		/*< 次の管理メモリへのポインタ	*/
	sc_unit_t        _data[1];	/*< データ領域					*/
} SC_MMgr;


/* メモリ操作関数	*/
void* SC_calloc (size_t nmemb, size_t size, const char* file, int line);
void* SC_malloc (size_t size ,              const char* file, int line);
void* SC_realloc(void*  ptr  , size_t size, const char* file, int line);
void  SC_free   (void*  ptr);

/* 本来のmalloc		*/
void* SC_realMalloc(size_t size);

/* ハンドラ関数		*/
void SC_MMgr_setHandler(
		void (*mHandler)(SC_MMgr*),
		void (*fHandler)(SC_MMgr*),
		void (*eHandler)(SC_MMgr*));

/* 管理エントリアクセスハンドラ	*/
void SC_MMgr_entries(void (*handler)(SC_MMgr*));

/* 強制メモリ開放				*/
void SC_MMgr_cleanup(const char* file, int line);



#ifdef SC_DEBUG
#define calloc(nmemb, size) SC_calloc(nmemb , size, __FILE__, __LINE__)
#define malloc(size)        SC_malloc(size        , __FILE__, __LINE__)
#define realloc(ptr, size)  SC_realloc(ptr  , size, __FILE__, __LINE__)
#define free(ptr)           SC_free(ptr)
#endif /* SC_DEBUG */

#ifdef __cplusplus
}
#endif

#endif	/* __SC_MMGR_H__ */

