/* $Id$
 * simple, very fast, malloc library
 * Copyright (C) 2001-2003 FhG Fokus
 * This file is part of ser, a free SIP server.
 * ser is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version
 * For a license to use the ser software under conditions
 * other than those described here, or to purchase support for this
 * software, please contact iptel.org by e-mail at the following addresses:
 *    info@iptel.org
 * ser is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License 
 * along with this program; if not, write to the Free Software 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * History:
 * --------
 *  2003-05-21  on sparc64 roundto 8 even in debugging mode (so malloc'ed
 *               long longs will be 64 bit aligned) (andrei)
 *  2004-07-19  support for 64 bit (2^64 mem. block) and more info
 *               for the future de-fragmentation support (andrei)
 *  2004-11-10  support for > 4Gb mem., switched to long (andrei)
 *  2007-06-23  added hash bitmap (andrei)

#if !defined(f_malloc_h)
#define f_malloc_h

#define DBG_F_MALLOC

#include "meminfo.h"

/* defs*/

/* use a bitmap to quickly find free fragments, should speed up
 * especially startup (non-warmed-up malloc) */

#if defined(__CPU_sparc64) || defined(__CPU_sparc)
/* tricky, on sun in 32 bits mode long long must be 64 bits aligned
 * but long can be 32 bits aligned => malloc should return long long
 * aligned memory */
	#define ROUNDTO		sizeof(long long)
	#define ROUNDTO		sizeof(void*) /* size we round to, must be = 2^n, and
                      sizeof(fm_frag) must be multiple of ROUNDTO !*/
#else /* DBG_F_MALLOC */
	#define ROUNDTO 8UL

#define F_MALLOC_OPTIMIZE_FACTOR 14UL /*used below */
								/* size to optimize for,
									(most allocs <= this size),
									must be 2^k */


typedef unsigned long fm_hash_bitmap_t;
#define FM_HASH_BMP_BITS  (sizeof(fm_hash_bitmap_t)*8)
#define FM_HASH_BMP_SIZE  \

/* hash structure:
 * 0 .... F_MALLOC_OPTIMIZE/ROUNDTO  - small buckets, size increases with
 *                            ROUNDTO from bucket to bucket
 * +1 .... end -  size = 2^k, big buckets */

struct fm_frag{
	unsigned long size;
		struct fm_frag* nxt_free;
		long reserved;
	const char* file;
	const char* func;
	unsigned long line;
	unsigned long check;

struct fm_frag_lnk{
	struct fm_frag* first;
	unsigned long no;

struct fm_block{
	unsigned long size; /* total size */
#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
	unsigned long used; /* alloc'ed size*/
	unsigned long real_used; /* used+malloc overhead*/
	unsigned long max_real_used;
	struct fm_frag* first_frag;
	struct fm_frag* last_frag;
	fm_hash_bitmap_t free_bitmap[FM_HASH_BMP_SIZE];
	struct fm_frag_lnk free_hash[F_HASH_SIZE];

struct fm_block* fm_malloc_init(char* address, unsigned long size);

void* fm_malloc(struct fm_block*, unsigned long size,
					const char* file, const char* func, unsigned int line);
void* fm_malloc(struct fm_block*, unsigned long size);

void  fm_free(struct fm_block*, void* p, const char* file, const char* func, 
				unsigned int line);
void  fm_free(struct fm_block*, void* p);

void*  fm_realloc(struct fm_block*, void* p, unsigned long size, 
					const char* file, const char* func, unsigned int line);
void*  fm_realloc(struct fm_block*, void* p, unsigned long size);

void  fm_status(struct fm_block*);
void  fm_info(struct fm_block*, struct mem_info*);

unsigned long fm_available(struct fm_block*);

void fm_sums(struct fm_block*);
#define fm_sums(v) do{}while(0)
#endif /* DBG_F_MALLOC */