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