... | ... |
@@ -28,7 +28,7 @@ NAME=ser |
28 | 28 |
# DEBUG compiles in some extra debugging code |
29 | 29 |
# OLD_PARSER uses the old and stable parser (from ser 8.3.2) |
30 | 30 |
# DNS_IP_HACK faster ip address resolver for ip strings (e.g "127.0.0.1") |
31 |
-DEFS=-DNOCR -DMACROEATER -DDNS_IP_HACK -DNO_DEBUG#-DSTATS -DNO_DEBUG |
|
31 |
+DEFS=-DNOCR -DMACROEATER -DDNS_IP_HACK #-DNO_DEBUG#-DSTATS -DNO_DEBUG |
|
32 | 32 |
#-DNO_LOG |
33 | 33 |
|
34 | 34 |
PROFILE= # -pg #set this if you want profiling |
... | ... |
@@ -4,6 +4,7 @@ |
4 | 4 |
|
5 | 5 |
#include "data_lump.h" |
6 | 6 |
#include "dprint.h" |
7 |
+#include "mem.h" |
|
7 | 8 |
|
8 | 9 |
#include <stdlib.h> |
9 | 10 |
|
... | ... |
@@ -200,18 +201,18 @@ void free_lump_list(struct lump* l) |
200 | 201 |
r=crt->before; |
201 | 202 |
while(r){ |
202 | 203 |
foo=r; r=r->before; |
203 |
- pkg_free_lump(foo); |
|
204 |
+ free_lump(foo); |
|
204 | 205 |
pkg_free(foo); |
205 | 206 |
} |
206 | 207 |
r=crt->after; |
207 | 208 |
while(r){ |
208 | 209 |
foo=r; r=r->after; |
209 |
- pkg_free_lump(foo); |
|
210 |
+ free_lump(foo); |
|
210 | 211 |
pkg_free(foo); |
211 | 212 |
} |
212 | 213 |
|
213 | 214 |
/*clean current elem*/ |
214 |
- pkg_free_lump(crt); |
|
215 |
+ free_lump(crt); |
|
215 | 216 |
pkg_free(crt); |
216 | 217 |
} |
217 | 218 |
} |
218 | 219 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,31 @@ |
1 |
+/* $Id$ |
|
2 |
+ * |
|
3 |
+ * memory related stuff (malloc & friends) |
|
4 |
+ * |
|
5 |
+ */ |
|
6 |
+ |
|
7 |
+ |
|
8 |
+#ifndef mem_h |
|
9 |
+#define mem_h |
|
10 |
+ |
|
11 |
+#ifdef PKG_MALLOC |
|
12 |
+#include "q_malloc.h" |
|
13 |
+ |
|
14 |
+extern struct qm_block* mem_block; |
|
15 |
+ |
|
16 |
+ |
|
17 |
+#define pkg_malloc(s) qm_malloc(mem_block, s) |
|
18 |
+#define pkg_free(p) qm_free(mem_block, p) |
|
19 |
+#define pkg_status() qm_status(mem_block) |
|
20 |
+ |
|
21 |
+#else |
|
22 |
+#include <stdlib.h> |
|
23 |
+ |
|
24 |
+#define pkg_malloc(s) malloc(s) |
|
25 |
+#define pkg_free(p) free(p) |
|
26 |
+#define pkg_status() |
|
27 |
+ |
|
28 |
+#endif |
|
29 |
+ |
|
30 |
+ |
|
31 |
+#endif |
28 | 29 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,232 @@ |
1 |
+/* $Id$ |
|
2 |
+ * |
|
3 |
+ */ |
|
4 |
+ |
|
5 |
+#define q_malloc |
|
6 |
+#ifdef q_malloc |
|
7 |
+ |
|
8 |
+#include "q_malloc.h" |
|
9 |
+#include "dprint.h" |
|
10 |
+ |
|
11 |
+ |
|
12 |
+/*usefull macros*/ |
|
13 |
+#define FRAG_END(f) \ |
|
14 |
+ ((struct qm_frag_end*)((char*)f+sizeof(struct qm_frag)+f->size)) |
|
15 |
+ |
|
16 |
+#define FRAG_NEXT(f) \ |
|
17 |
+ ((struct qm_frag*)((char*)f+sizeof(struct qm_frag)+f->size+ \ |
|
18 |
+ sizeof(struct qm_frag_end))) |
|
19 |
+ |
|
20 |
+#define FRAG_PREV(f) \ |
|
21 |
+ ( (struct qm_frag*) ( ((char*)f-sizeof(struct qm_frag_end))- \ |
|
22 |
+ ((struct qm_frag_end*)((char*)f-sizeof(struct qm_frag_end)))->size- \ |
|
23 |
+ sizeof(struct qm_frag) ) ) |
|
24 |
+ |
|
25 |
+ |
|
26 |
+ |
|
27 |
+ |
|
28 |
+ |
|
29 |
+/* init malloc and return a qm_block*/ |
|
30 |
+struct qm_block* qm_malloc_init(char* address, unsigned int size) |
|
31 |
+{ |
|
32 |
+ char* start; |
|
33 |
+ char* end; |
|
34 |
+ struct qm_block* qm; |
|
35 |
+ unsigned int init_overhead; |
|
36 |
+ unsigned int init_size; |
|
37 |
+ |
|
38 |
+ init_size=size; |
|
39 |
+ /* make address and size multiple of 8*/ |
|
40 |
+ start=(char*)( ((unsigned int)address%8)?((unsigned int)address+8)/8*8: |
|
41 |
+ (unsigned int)address); |
|
42 |
+ if (size<start-address) return 0; |
|
43 |
+ size-=(start-address); |
|
44 |
+ if (size <8) return 0; |
|
45 |
+ size=(size%8)?(size-8)/8*8:size; |
|
46 |
+ |
|
47 |
+ init_overhead=sizeof(struct qm_block)+sizeof(struct qm_frag)+ |
|
48 |
+ sizeof(struct qm_frag_end); |
|
49 |
+ if (size < init_overhead) |
|
50 |
+ { |
|
51 |
+ /* not enough mem to create our control structures !!!*/ |
|
52 |
+ return 0; |
|
53 |
+ } |
|
54 |
+ end=start+size; |
|
55 |
+ qm=(struct qm_block*)start; |
|
56 |
+ memset(qm, 0, sizeof(struct qm_block)); |
|
57 |
+ qm->init_size=init_size; |
|
58 |
+ qm->size=size-init_overhead; |
|
59 |
+ qm->real_used=init_overhead; |
|
60 |
+ |
|
61 |
+ qm->first_frag=(struct qm_frag*)(start+sizeof(struct qm_block)); |
|
62 |
+ qm->last_frag_end=(struct qm_frag_end*)(end-sizeof(struct qm_frag_end)); |
|
63 |
+ /* init initial fragment*/ |
|
64 |
+ qm->first_frag->size=size; |
|
65 |
+ qm->first_frag->u.nxt_free=&(qm->free_lst); |
|
66 |
+ qm->last_frag_end->size=size; |
|
67 |
+ qm->last_frag_end->prev_free=&(qm->free_lst); |
|
68 |
+ /* init free_lst* */ |
|
69 |
+ qm->free_lst.u.nxt_free=qm->first_frag; |
|
70 |
+ qm->free_lst_end.prev_free=qm->first_frag; |
|
71 |
+ qm->free_lst.size=0; |
|
72 |
+ qm->free_lst_end.size=0; |
|
73 |
+ |
|
74 |
+ |
|
75 |
+ return qm; |
|
76 |
+} |
|
77 |
+ |
|
78 |
+ |
|
79 |
+static inline void qm_insert_free(struct qm_block* qm, struct qm_frag* frag) |
|
80 |
+{ |
|
81 |
+ struct qm_frag* f; |
|
82 |
+ struct qm_frag* prev; |
|
83 |
+ |
|
84 |
+ for(f=qm->free_lst.u.nxt_free; f!=&(qm->free_lst); f=f->u.nxt_free){ |
|
85 |
+ if (frag->size < f->size) break; |
|
86 |
+ } |
|
87 |
+ /*insert it here*/ |
|
88 |
+ prev=FRAG_END(f)->prev_free; |
|
89 |
+ prev->u.nxt_free=frag; |
|
90 |
+ FRAG_END(frag)->prev_free=prev; |
|
91 |
+ frag->u.nxt_free=f; |
|
92 |
+ FRAG_END(f)->prev_free=frag; |
|
93 |
+} |
|
94 |
+ |
|
95 |
+ |
|
96 |
+ |
|
97 |
+static inline void qm_detach_free(struct qm_block* qm, struct qm_frag* frag) |
|
98 |
+{ |
|
99 |
+ struct qm_frag *prev; |
|
100 |
+ struct qm_frag *next; |
|
101 |
+ |
|
102 |
+ struct qm_frag_end *end; |
|
103 |
+ |
|
104 |
+ prev=FRAG_END(frag)->prev_free; |
|
105 |
+ next=frag->u.nxt_free; |
|
106 |
+ prev->u.nxt_free=next; |
|
107 |
+ FRAG_END(next)->prev_free=prev; |
|
108 |
+ |
|
109 |
+} |
|
110 |
+ |
|
111 |
+ |
|
112 |
+ |
|
113 |
+void* qm_malloc(struct qm_block* qm, unsigned int size) |
|
114 |
+{ |
|
115 |
+ struct qm_frag* f; |
|
116 |
+ struct qm_frag_end* end; |
|
117 |
+ struct qm_frag* n; |
|
118 |
+ unsigned int rest; |
|
119 |
+ unsigned int overhead; |
|
120 |
+ |
|
121 |
+ /*size must be a multiple of 8*/ |
|
122 |
+ size=(size%8)?(size+8)/8*8:size; |
|
123 |
+ if (size>(qm->size-qm->real_used)) return 0; |
|
124 |
+ if (qm->free_lst.u.nxt_free==&(qm->free_lst)) return 0; |
|
125 |
+ /*search for a suitable free frag*/ |
|
126 |
+ for (f=qm->free_lst.u.nxt_free; f!=&(qm->free_lst); f=f->u.nxt_free){ |
|
127 |
+ if (f->size>=size){ |
|
128 |
+ /* we found it!*/ |
|
129 |
+ /*detach it from the free list*/ |
|
130 |
+ qm_detach_free(qm, f); |
|
131 |
+ /*mark it as "busy"*/ |
|
132 |
+ f->u.is_free=0; |
|
133 |
+ |
|
134 |
+ /*see if we'll use full frag, or we'll split it in 2*/ |
|
135 |
+ rest=f->size-size; |
|
136 |
+ overhead=sizeof(struct qm_frag)+sizeof(struct qm_frag_end); |
|
137 |
+ if (rest>overhead){ |
|
138 |
+ f->size=size; |
|
139 |
+ /*split the fragment*/ |
|
140 |
+ end=FRAG_END(f); |
|
141 |
+ end->size=size; |
|
142 |
+ n=(struct qm_frag*)((char*)end+sizeof(struct qm_frag_end)); |
|
143 |
+ n->size=rest-overhead; |
|
144 |
+ FRAG_END(n)->size=n->size; |
|
145 |
+ qm->real_used+=overhead; |
|
146 |
+ /* reinsert n in free list*/ |
|
147 |
+ qm_insert_free(qm, n); |
|
148 |
+ }else{ |
|
149 |
+ /* we cannot split this fragment any more => alloc all of it*/ |
|
150 |
+ } |
|
151 |
+ qm->real_used+=f->size; |
|
152 |
+ qm->used+=f->size; |
|
153 |
+ return (char*)f+sizeof(struct qm_frag); |
|
154 |
+ } |
|
155 |
+ } |
|
156 |
+ return 0; |
|
157 |
+} |
|
158 |
+ |
|
159 |
+ |
|
160 |
+ |
|
161 |
+void qm_free(struct qm_block* qm, void* p) |
|
162 |
+{ |
|
163 |
+ struct qm_frag* f; |
|
164 |
+ struct qm_frag* prev; |
|
165 |
+ struct qm_frag* next; |
|
166 |
+ struct qm_frag_end *end; |
|
167 |
+ unsigned int overhead; |
|
168 |
+ unsigned int size; |
|
169 |
+ |
|
170 |
+ if (p==0) { |
|
171 |
+ DBG("WARNING:qm_free: free(0) called\n"); |
|
172 |
+ return; |
|
173 |
+ } |
|
174 |
+ prev=next=0; |
|
175 |
+ f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag)); |
|
176 |
+ overhead=sizeof(struct qm_frag)+sizeof(struct qm_frag_end); |
|
177 |
+ next=FRAG_NEXT(f); |
|
178 |
+ size=f->size; |
|
179 |
+ qm->used-=size; |
|
180 |
+ qm->real_used-=size; |
|
181 |
+ if (((char*)next < (char*)qm->last_frag_end) &&( next->u.is_free)){ |
|
182 |
+ /* join */ |
|
183 |
+ qm_detach_free(qm, next); |
|
184 |
+ size+=next->size+overhead; |
|
185 |
+ qm->real_used-=overhead; |
|
186 |
+ } |
|
187 |
+ |
|
188 |
+ if (f > qm->first_frag){ |
|
189 |
+ prev=FRAG_PREV(f); |
|
190 |
+ /* (struct qm_frag*)((char*)f - (struct qm_frag_end*)((char*)f- |
|
191 |
+ sizeof(struct qm_frag_end))->size);*/ |
|
192 |
+ if (prev->u.is_free){ |
|
193 |
+ /*join*/ |
|
194 |
+ qm_detach_free(qm, prev); |
|
195 |
+ size+=prev->size+overhead; |
|
196 |
+ qm->real_used-=overhead; |
|
197 |
+ f=prev; |
|
198 |
+ } |
|
199 |
+ } |
|
200 |
+ FRAG_END(f)->size=f->size; |
|
201 |
+ qm_insert_free(qm, f); |
|
202 |
+} |
|
203 |
+ |
|
204 |
+ |
|
205 |
+ |
|
206 |
+void qm_status(struct qm_block* qm) |
|
207 |
+{ |
|
208 |
+ struct qm_frag* f; |
|
209 |
+ int i; |
|
210 |
+ |
|
211 |
+ DBG("qm_status (%x):\n", qm); |
|
212 |
+ DBG(" init_size= %d", qm->init_size); |
|
213 |
+ DBG(" heap size= %d", qm->size); |
|
214 |
+ DBG(" used= %d, used+overhead=%d, free=%d\n", |
|
215 |
+ qm->used, qm->real_used, qm->size-qm->real_used); |
|
216 |
+ |
|
217 |
+ DBG("dumping all fragments:\n"); |
|
218 |
+ for (f=qm->first_frag, i=0;(char*)f<(char*)qm->last_frag_end;f=FRAG_NEXT(f) |
|
219 |
+ ,i++) |
|
220 |
+ DBG(" %3d. %c address=%x size=%d\n", i, (f->u.is_free)?'a':'N', |
|
221 |
+ (char*)f+sizeof(struct qm_frag), f->size); |
|
222 |
+ DBG("dumping free list:\n"); |
|
223 |
+ for (f=qm->free_lst.u.nxt_free; f!=&(qm->free_lst); f=f->u.nxt_free) |
|
224 |
+ DBG(" %3d. %c address=%x size=%d\n", i, (f->u.is_free)?'a':'N', |
|
225 |
+ (char*)f+sizeof(struct qm_frag), f->size); |
|
226 |
+ DBG("-----------------------------\n"); |
|
227 |
+} |
|
228 |
+ |
|
229 |
+ |
|
230 |
+ |
|
231 |
+ |
|
232 |
+#endif |
0 | 233 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,45 @@ |
1 |
+/* $Id$ |
|
2 |
+ * |
|
3 |
+ * simple & fast malloc library |
|
4 |
+ */ |
|
5 |
+ |
|
6 |
+#ifndef q_malloc_h |
|
7 |
+#define q_malloc_h |
|
8 |
+ |
|
9 |
+ |
|
10 |
+struct qm_frag{ |
|
11 |
+ unsigned int size; |
|
12 |
+ union{ |
|
13 |
+ struct qm_frag* nxt_free; |
|
14 |
+ int is_free; |
|
15 |
+ }u; |
|
16 |
+}; |
|
17 |
+ |
|
18 |
+struct qm_frag_end{ |
|
19 |
+ unsigned int size; |
|
20 |
+ struct qm_frag* prev_free; |
|
21 |
+}; |
|
22 |
+ |
|
23 |
+ |
|
24 |
+struct qm_block{ |
|
25 |
+ unsigned int init_size; |
|
26 |
+ unsigned int size; /* total size */ |
|
27 |
+ unsigned int used; /* alloc'ed size*/ |
|
28 |
+ unsigned int real_used; /* used+malloc overhead*/ |
|
29 |
+ |
|
30 |
+ struct qm_frag* first_frag; |
|
31 |
+ struct qm_frag_end* last_frag_end; |
|
32 |
+ |
|
33 |
+ struct qm_frag free_lst; |
|
34 |
+ struct qm_frag_end free_lst_end; |
|
35 |
+}; |
|
36 |
+ |
|
37 |
+ |
|
38 |
+ |
|
39 |
+struct qm_block* qm_malloc_init(char* address, unsigned int size); |
|
40 |
+void* qm_malloc(struct qm_block*, unsigned int size); |
|
41 |
+void qm_free(struct qm_block*, void* p); |
|
42 |
+void qm_status(struct qm_block*); |
|
43 |
+ |
|
44 |
+ |
|
45 |
+#endif |
... | ... |
@@ -11,6 +11,7 @@ |
11 | 11 |
#include "msg_parser.h" |
12 | 12 |
#include "forward.h" |
13 | 13 |
#include "action.h" |
14 |
+#include "mem.h" |
|
14 | 15 |
|
15 | 16 |
|
16 | 17 |
#ifdef DEBUG_DMALLOC |
... | ... |
@@ -27,7 +28,7 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip) |
27 | 28 |
{ |
28 | 29 |
struct sip_msg* msg; |
29 | 30 |
|
30 |
- msg=pkt_malloc(sizeof(struct sip_msg)); |
|
31 |
+ msg=pkg_malloc(sizeof(struct sip_msg)); |
|
31 | 32 |
if (msg==0) goto error1; |
32 | 33 |
msg_no++; |
33 | 34 |
#ifdef STATS |
... | ... |
@@ -41,7 +42,7 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip) |
41 | 42 |
msg->src_ip=src_ip; |
42 | 43 |
msg->id=msg_no; |
43 | 44 |
/* make a copy of the message */ |
44 |
- msg->orig=(char*) pkt_malloc(len+1); |
|
45 |
+ msg->orig=(char*) pkg_malloc(len+1); |
|
45 | 46 |
if (msg->orig==0){ |
46 | 47 |
LOG(L_ERR, "ERROR:receive_msg: memory allocation failure\n"); |
47 | 48 |
goto error1; |
... | ... |
@@ -108,7 +109,7 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip) |
108 | 109 |
skip: |
109 | 110 |
DBG("skip:...\n"); |
110 | 111 |
free_sip_msg(msg); |
111 |
- pkt_free(msg); |
|
112 |
+ pkg_free(msg); |
|
112 | 113 |
#ifdef STATS |
113 | 114 |
if (skipped) update_received_drops; |
114 | 115 |
#endif |
... | ... |
@@ -116,14 +117,14 @@ skip: |
116 | 117 |
error: |
117 | 118 |
DBG("error:...\n"); |
118 | 119 |
free_sip_msg(msg); |
119 |
- pkt_free(msg); |
|
120 |
+ pkg_free(msg); |
|
120 | 121 |
#ifdef STATS |
121 | 122 |
update_received_drops; |
122 | 123 |
#endif |
123 | 124 |
return -1; |
124 | 125 |
error1: |
125 |
- if (msg) pkt_free(msg); |
|
126 |
- pkt_free(buf); |
|
126 |
+ if (msg) pkg_free(msg); |
|
127 |
+ pkg_free(buf); |
|
127 | 128 |
#ifdef STATS |
128 | 129 |
update_received_drops; |
129 | 130 |
#endif |
... | ... |
@@ -14,6 +14,7 @@ |
14 | 14 |
#include "config.h" |
15 | 15 |
#include "dprint.h" |
16 | 16 |
#include "receive.h" |
17 |
+#include "mem.h" |
|
17 | 18 |
|
18 | 19 |
#ifdef DEBUG_DMALLOC |
19 | 20 |
#include <dmalloc.h> |
... | ... |
@@ -153,7 +154,7 @@ int udp_rcv_loop() |
153 | 154 |
struct sockaddr* from; |
154 | 155 |
int fromlen; |
155 | 156 |
|
156 |
- buf=pkt_malloc(BUF_SIZE+1); |
|
157 |
+ buf=pkg_malloc(BUF_SIZE+1); |
|
157 | 158 |
if (buf==0){ |
158 | 159 |
LOG(L_ERR, "ERROR: udp_rcv_loop: could not allocate receive" |
159 | 160 |
" buffer\n"); |