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 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
... ...
@@ -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 929
 
929 930
 
930 931
 
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 @@
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");