4b50c7f1030b6eec231594435b328737a30f180a
[sip-router] / mem / q_malloc.h
1 /* $Id$
2  *
3  * simple & fast malloc library
4  *
5  * Copyright (C) 2001-2003 FhG Fokus
6  *
7  * This file is part of sip-router, a free SIP server.
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 /*
22  * History:
23  * --------
24  *  2003-05-21  on sparc64 roundto 8 even in debugging mode (so malloc'ed
25  *               long longs will be 64 bit aligned) (andrei)
26  *  2004-07-19  support for 64 bit (2^64 mem. block) and more info
27  *               for the future de-fragmentation support (andrei)
28  *  2004-11-10  support for > 4Gb mem. (switched to long) (andrei)
29  */
30
31
32 #if !defined(q_malloc_h) && !defined(F_MALLOC)
33 #define q_malloc_h
34
35 #include "meminfo.h"
36
37 /* defs*/
38 #ifdef DBG_QM_MALLOC
39 #if defined(__CPU_sparc64) || defined(__CPU_sparc)
40 /* tricky, on sun in 32 bits mode long long must be 64 bits aligned
41  * but long can be 32 bits aligned => malloc should return long long
42  * aligned memory */
43         #define ROUNDTO         sizeof(long long)
44 #else
45         #define ROUNDTO         sizeof(void*) /* minimum possible ROUNDTO ->heavy 
46                                                                                  debugging*/
47 #endif 
48 #else /* DBG_QM_MALLOC */
49         #define ROUNDTO         16UL /* size we round to, must be = 2^n  and also
50                                                          sizeof(qm_frag)+sizeof(qm_frag_end)
51                                                          must be multiple of ROUNDTO!
52                                                    */
53 #endif
54 #define MIN_FRAG_SIZE   ROUNDTO
55
56
57
58 #define QM_MALLOC_OPTIMIZE_FACTOR 14UL /*used below */
59 #define QM_MALLOC_OPTIMIZE  ((unsigned long)(1UL<<QM_MALLOC_OPTIMIZE_FACTOR))
60                                                                 /* size to optimize for,
61                                                                         (most allocs <= this size),
62                                                                         must be 2^k */
63
64 #define QM_HASH_SIZE ((unsigned long)(QM_MALLOC_OPTIMIZE/ROUNDTO + \
65                 (sizeof(long)*8-QM_MALLOC_OPTIMIZE_FACTOR)+1))
66
67 /* hash structure:
68  * 0 .... QM_MALLOC_OPTIMIE/ROUNDTO  - small buckets, size increases with
69  *                            ROUNDTO from bucket to bucket
70  * +1 .... end -  size = 2^k, big buckets */
71
72 struct qm_frag{
73         unsigned long size;
74         union{
75                 struct qm_frag* nxt_free;
76                 long is_free;
77         }u;
78 #ifdef DBG_QM_MALLOC
79         const char* file;
80         const char* func;
81         unsigned long line;
82         unsigned long check;
83 #endif
84 };
85
86 struct qm_frag_end{
87 #ifdef DBG_QM_MALLOC
88         unsigned long check1;
89         unsigned long check2;
90         unsigned long reserved1;
91         unsigned long reserved2;
92 #endif
93         unsigned long size;
94         struct qm_frag* prev_free;
95 };
96
97
98
99 struct qm_frag_lnk{
100         struct qm_frag head;
101         struct qm_frag_end tail;
102         unsigned long no;
103 };
104
105
106 struct qm_block{
107         unsigned long size; /* total size */
108         unsigned long used; /* alloc'ed size*/
109         unsigned long real_used; /* used+malloc overhead*/
110         unsigned long max_real_used;
111         
112         struct qm_frag* first_frag;
113         struct qm_frag_end* last_frag_end;
114         
115         struct qm_frag_lnk free_hash[QM_HASH_SIZE];
116         /*struct qm_frag_end free_lst_end;*/
117 };
118
119
120
121 struct qm_block* qm_malloc_init(char* address, unsigned long size);
122
123 #ifdef DBG_QM_MALLOC
124 void* qm_malloc(struct qm_block*, unsigned long size, const char* file,
125                                         const char* func, unsigned int line);
126 #else
127 void* qm_malloc(struct qm_block*, unsigned long size);
128 #endif
129
130 #ifdef DBG_QM_MALLOC
131 void  qm_free(struct qm_block*, void* p, const char* file, const char* func, 
132                                 unsigned int line);
133 #else
134 void  qm_free(struct qm_block*, void* p);
135 #endif
136 #ifdef DBG_QM_MALLOC
137 void* qm_realloc(struct qm_block*, void* p, unsigned long size,
138                                         const char* file, const char* func, unsigned int line);
139 #else
140 void* qm_realloc(struct qm_block*, void* p, unsigned long size);
141 #endif
142
143 void  qm_status(struct qm_block*);
144 void  qm_check(struct qm_block*);
145 void  qm_info(struct qm_block*, struct mem_info*);
146
147 unsigned long qm_available(struct qm_block* qm);
148
149 #ifdef DBG_QM_MALLOC
150 void qm_sums(struct qm_block* qm);
151 #else
152 #define qm_sums(v) do{}while(0)
153 #endif /*DBQ_QM_MALLOC */
154
155 #endif