Browse code

- malloc replacements

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