mem/q_malloc.h
47f59303
 /*
84d8e165
  * Copyright (C) 2001-2003 FhG Fokus
7dd0b342
  *
e4f42ce1
  * This file is part of sip-router, a free SIP server.
7dd0b342
  *
e4f42ce1
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
7dd0b342
  *
e4f42ce1
  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
6fa79282
  */
47f59303
 
f72c2aae
 /*
  * History:
  * --------
  *  2003-05-21  on sparc64 roundto 8 even in debugging mode (so malloc'ed
  *               long longs will be 64 bit aligned) (andrei)
46b467df
  *  2004-07-19  support for 64 bit (2^64 mem. block) and more info
  *               for the future de-fragmentation support (andrei)
c082177a
  *  2004-11-10  support for > 4Gb mem. (switched to long) (andrei)
f72c2aae
  */
6fa79282
 
47f59303
 /**
  * \file
  * \brief Simple & fast malloc library
  * \ingroup mem
  */
7dd0b342
 
f92113d8
 #if !defined(q_malloc_h) && !defined(F_MALLOC)
6fa79282
 #define q_malloc_h
 
51dffb0a
 #include "meminfo.h"
eca7f442
 
 /* defs*/
09b2f164
 #ifdef DBG_QM_MALLOC
245b8b93
 #if defined(__CPU_sparc64) || defined(__CPU_sparc)
f72c2aae
 /* 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)
 #else
09d47401
 	#define ROUNDTO		sizeof(void*) /* minimum possible ROUNDTO ->heavy 
 										 debugging*/
f72c2aae
 #endif 
 #else /* DBG_QM_MALLOC */
c082177a
 	#define ROUNDTO		16UL /* size we round to, must be = 2^n  and also
09b2f164
 							 sizeof(qm_frag)+sizeof(qm_frag_end)
84d8e165
 							 must be multiple of ROUNDTO!
09b2f164
 						   */
 #endif
eca7f442
 #define MIN_FRAG_SIZE	ROUNDTO
 
 
 
dca4cad0
 #define QM_MALLOC_OPTIMIZE_FACTOR 14UL /*used below */
c082177a
 #define QM_MALLOC_OPTIMIZE  ((unsigned long)(1UL<<QM_MALLOC_OPTIMIZE_FACTOR))
eca7f442
 								/* size to optimize for,
46b467df
 									(most allocs <= this size),
eca7f442
 									must be 2^k */
 
9a694681
 #define QM_HASH_SIZE ((unsigned long)(QM_MALLOC_OPTIMIZE/ROUNDTO + \
4d080f49
 		(sizeof(long)*8-QM_MALLOC_OPTIMIZE_FACTOR)+1))
eca7f442
 
 /* hash structure:
  * 0 .... QM_MALLOC_OPTIMIE/ROUNDTO  - small buckets, size increases with
  *                            ROUNDTO from bucket to bucket
  * +1 .... end -  size = 2^k, big buckets */
 
6fa79282
 struct qm_frag{
85f1f3ee
 	unsigned long size;
6fa79282
 	union{
 		struct qm_frag* nxt_free;
85f1f3ee
 		long is_free;
6fa79282
 	}u;
b4d048d4
 #ifdef DBG_QM_MALLOC
4168f707
 	const char* file;
 	const char* func;
85f1f3ee
 	unsigned long line;
 	unsigned long check;
b4d048d4
 #endif
6fa79282
 };
 
 struct qm_frag_end{
2c65bd8b
 #ifdef DBG_QM_MALLOC
85f1f3ee
 	unsigned long check1;
 	unsigned long check2;
 	unsigned long reserved1;
 	unsigned long reserved2;
2c65bd8b
 #endif
85f1f3ee
 	unsigned long size;
6fa79282
 	struct qm_frag* prev_free;
 };
 
 
eca7f442
 
46b467df
 struct qm_frag_lnk{
eca7f442
 	struct qm_frag head;
 	struct qm_frag_end tail;
46b467df
 	unsigned long no;
eca7f442
 };
 
 
47f59303
 /**
  * \brief Block of memory for Q_MALLOC memory manager
  * \see mem_info
  */
 
6fa79282
 struct qm_block{
85f1f3ee
 	unsigned long size; /* total size */
 	unsigned long used; /* alloc'ed size*/
 	unsigned long real_used; /* used+malloc overhead*/
 	unsigned long max_real_used;
6fa79282
 	
 	struct qm_frag* first_frag;
 	struct qm_frag_end* last_frag_end;
 	
46b467df
 	struct qm_frag_lnk free_hash[QM_HASH_SIZE];
eca7f442
 	/*struct qm_frag_end free_lst_end;*/
6fa79282
 };
 
 
 
c082177a
 struct qm_block* qm_malloc_init(char* address, unsigned long size);
b4d048d4
 
 #ifdef DBG_QM_MALLOC
4168f707
 void* qm_malloc(struct qm_block*, unsigned long size, const char* file,
 					const char* func, unsigned int line);
b4d048d4
 #else
c082177a
 void* qm_malloc(struct qm_block*, unsigned long size);
b4d048d4
 #endif
 
 #ifdef DBG_QM_MALLOC
4168f707
 void  qm_free(struct qm_block*, void* p, const char* file, const char* func, 
b4d048d4
 				unsigned int line);
 #else
6fa79282
 void  qm_free(struct qm_block*, void* p);
b4d048d4
 #endif
f22b996b
 #ifdef DBG_QM_MALLOC
c082177a
 void* qm_realloc(struct qm_block*, void* p, unsigned long size,
4168f707
 					const char* file, const char* func, unsigned int line);
f22b996b
 #else
c082177a
 void* qm_realloc(struct qm_block*, void* p, unsigned long size);
f22b996b
 #endif
b4d048d4
 
6fa79282
 void  qm_status(struct qm_block*);
e5931954
 void  qm_check(struct qm_block*);
473f6f2e
 void  qm_info(struct qm_block*, struct mem_info*);
6fa79282
 
8799e028
 unsigned long qm_available(struct qm_block* qm);
6fa79282
 
ed20ee1d
 #ifdef DBG_QM_MALLOC
 void qm_sums(struct qm_block* qm);
 #else
 #define qm_sums(v) do{}while(0)
 #endif /*DBQ_QM_MALLOC */
 
6fa79282
 #endif