Browse code

- forgot to add f_malloc.*

Andrei Pelinescu-Onciul authored on 12/02/2002 20:10:45
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,293 @@
1
+/* $Id$
2
+ *
3
+ */
4
+
5
+#if !defined(q_malloc) && !(defined VQ_MALLOC) 
6
+
7
+#include "f_malloc.h"
8
+#include "../dprint.h"
9
+
10
+
11
+/*useful macros*/
12
+
13
+#define FRAG_NEXT(f) \
14
+	((struct fm_frag*)((char*)(f)+sizeof(struct fm_frag)+(f)->size ))
15
+
16
+#define FRAG_OVERHEAD	(sizeof(struct fm_frag))
17
+
18
+
19
+#define ROUNDUP(s)		(((s)%ROUNDTO)?((s)+ROUNDTO)/ROUNDTO*ROUNDTO:(s))
20
+#define ROUNDDOWN(s)	(((s)%ROUNDTO)?((s)-ROUNDTO)/ROUNDTO*ROUNDTO:(s))
21
+
22
+
23
+
24
+	/* finds the hash value for s, s=ROUNDTO multiple*/
25
+#define GET_HASH(s)   ( ((s)<F_MALLOC_OPTIMIZE)?(s)/ROUNDTO: \
26
+						F_MALLOC_OPTIMIZE/ROUNDTO+big_hash_idx((s))- \
27
+							F_MALLOC_OPTIMIZE_FACTOR+1 )
28
+
29
+
30
+/* computes hash number for big buckets*/
31
+inline static int big_hash_idx(int s)
32
+{
33
+	int idx;
34
+	/* s is rounded => s = k*2^n (ROUNDTO=2^n) 
35
+	 * index= i such that 2^i > s >= 2^(i-1)
36
+	 *
37
+	 * => index = number of the first non null bit in s*/
38
+	for (idx=31; !(s&0x80000000) ; s<<=1, idx--);
39
+	return idx;
40
+}
41
+
42
+
43
+#ifdef DBG_F_MALLOC
44
+#define ST_CHECK_PATTERN   0xf0f0f0f0
45
+#define END_CHECK_PATTERN1 0xc0c0c0c0
46
+#define END_CHECK_PATTERN2 0xabcdefed
47
+#endif
48
+
49
+
50
+
51
+static inline void fm_insert_free(struct fm_block* qm, struct fm_frag* frag)
52
+{
53
+	struct fm_frag** f;
54
+	int hash;
55
+	
56
+	hash=GET_HASH(frag->size);
57
+	f=&(qm->free_hash[hash]);
58
+	if (frag->size > F_MALLOC_OPTIMIZE){
59
+		for(; *f; f=&((*f)->u.nxt_free)){
60
+			if (frag->size <= (*f)->size) break;
61
+		}
62
+	}
63
+	
64
+	/*insert it here*/
65
+	frag->u.nxt_free=*f;
66
+	*f=frag;
67
+}
68
+
69
+
70
+
71
+/* init malloc and return a qm_block*/
72
+struct fm_block* fm_malloc_init(char* address, unsigned int size)
73
+{
74
+	char* start;
75
+	char* end;
76
+	struct fm_block* qm;
77
+	unsigned int init_overhead;
78
+	int h;
79
+	
80
+	/* make address and size multiple of 8*/
81
+	start=(char*)ROUNDUP((unsigned int) address);
82
+	if (size<start-address) return 0;
83
+	size-=(start-address);
84
+	if (size <(MIN_FRAG_SIZE+FRAG_OVERHEAD)) return 0;
85
+	size=ROUNDDOWN(size);
86
+
87
+	init_overhead=(ROUNDUP(sizeof(struct fm_block))+sizeof(struct fm_frag));
88
+	
89
+	
90
+	if (size < init_overhead)
91
+	{
92
+		/* not enough mem to create our control structures !!!*/
93
+		return 0;
94
+	}
95
+	end=start+size;
96
+	qm=(struct fm_block*)start;
97
+	memset(qm, 0, sizeof(struct fm_block));
98
+	size-=init_overhead;
99
+	qm->size=size;
100
+#ifdef DBG_F_MALLOC
101
+	qm->real_used=init_overhead;
102
+	qm->max_real_used=qm->real_used;
103
+#endif
104
+	
105
+	qm->first_frag=(struct fm_frag*)(start+ROUNDUP(sizeof(struct fm_block)));
106
+	qm->last_frag=(struct fm_frag*)(end-sizeof(struct fm_frag));
107
+	/* init initial fragment*/
108
+	qm->first_frag->size=size;
109
+	qm->last_frag->size=0;
110
+	
111
+#ifdef DBG_F_MALLOC
112
+	qm->first_frag->check=ST_CHECK_PATTERN;
113
+	qm->last_frag->check=END_CHECK_PATTERN1;
114
+#endif
115
+	
116
+	/* link initial fragment into the free list*/
117
+	
118
+	fm_insert_free(qm, qm->first_frag);
119
+	
120
+	
121
+	return qm;
122
+}
123
+
124
+
125
+
126
+#ifdef DBG_F_MALLOC
127
+void* fm_malloc(struct fm_block* qm, unsigned int size, char* file, char* func,
128
+					unsigned int line)
129
+#else
130
+void* fm_malloc(struct fm_block* qm, unsigned int size)
131
+#endif
132
+{
133
+	struct fm_frag** f;
134
+	struct fm_frag* frag;
135
+	struct fm_frag* n;
136
+	unsigned int rest;
137
+	int hash;
138
+	
139
+#ifdef DBG_F_MALLOC
140
+	DBG("fm_malloc(%x, %d) called from %s: %s(%d)\n", qm, size, file, func,
141
+			line);
142
+#endif
143
+	/*size must be a multiple of 8*/
144
+	size=ROUNDUP(size);
145
+/*	if (size>(qm->size-qm->real_used)) return 0; */
146
+
147
+	
148
+	/*search for a suitable free frag*/
149
+
150
+	for(hash=GET_HASH(size);hash<F_HASH_SIZE;hash++){
151
+		f=&(qm->free_hash[hash]);
152
+		for(;(*f); f=&((*f)->u.nxt_free))
153
+			if ((*f)->size>=size) goto found;
154
+		/* try in a bigger bucket */
155
+	}
156
+	/* not found, bad! */
157
+	return 0;
158
+
159
+found:
160
+	/* we found it!*/
161
+	/* detach it from the free list*/
162
+	frag=*f;
163
+	*f=frag->u.nxt_free;
164
+	
165
+	/*see if we'll use full frag, or we'll split it in 2*/
166
+	rest=frag->size-size;
167
+	if (rest>(FRAG_OVERHEAD+MIN_FRAG_SIZE)){
168
+		frag->size=size;
169
+		/*split the fragment*/
170
+		n=FRAG_NEXT(frag);
171
+		n->size=rest-FRAG_OVERHEAD;
172
+#ifdef DBG_F_MALLOC
173
+		qm->real_used+=FRAG_OVERHEAD;
174
+		/* frag created by malloc, mark it*/
175
+		n->file=file;
176
+		n->func="frag. from qm_malloc";
177
+		n->line=line;
178
+		n->check=ST_CHECK_PATTERN;
179
+#endif
180
+		/* reinsert n in free list*/
181
+		fm_insert_free(qm, n);
182
+	}else{
183
+		/* we cannot split this fragment any more => alloc all of it*/
184
+	}
185
+#ifdef DBG_F_MALLOC
186
+	qm->real_used+=frag->size;
187
+	qm->used+=frag->size;
188
+
189
+	if (qm->max_real_used<qm->real_used)
190
+		qm->max_real_used=qm->real_used;
191
+
192
+	frag->file=file;
193
+	frag->func=func;
194
+	frag->line=line;
195
+	frag->check=ST_CHECK_PATTERN;
196
+	DBG("fm_malloc(%x, %d) returns address %x \n", qm, size,
197
+		(char*)frag+sizeof(struct fm_frag));
198
+#endif
199
+	return (char*)frag+sizeof(struct fm_frag);
200
+}
201
+
202
+
203
+
204
+#ifdef DBG_F_MALLOC
205
+void fm_free(struct fm_block* qm, void* p, char* file, char* func, 
206
+				unsigned int line)
207
+#else
208
+void fm_free(struct fm_block* qm, void* p)
209
+#endif
210
+{
211
+	struct fm_frag* f;
212
+	unsigned int size;
213
+
214
+#ifdef DBG_F_MALLOC
215
+	DBG("fm_free(%x, %x), called from %s: %s(%d)\n", qm, p, file, func, line);
216
+	if (p>(void*)qm->last_frag || p<(void*)qm->first_frag){
217
+		LOG(L_CRIT, "BUG: fm_free: bad pointer %x (out of memory block!) - "
218
+				"aborting\n", p);
219
+		abort();
220
+	}
221
+#endif
222
+	if (p==0) {
223
+		LOG(L_WARN, "WARNING:fm_free: free(0) called\n");
224
+		return;
225
+	}
226
+	f=(struct fm_frag*) ((char*)p-sizeof(struct fm_frag));
227
+#ifdef DBG_F_MALLOC
228
+	DBG("fm_free: freeing block alloc'ed from %s: %s(%d)\n", f->file, f->func,
229
+			f->line);
230
+#endif
231
+	size=f->size;
232
+
233
+#ifdef DBG_F_MALLOC
234
+	qm->used-=size;
235
+	qm->real_used-=size;
236
+	f->file=file;
237
+	f->func=func;
238
+	f->line=line;
239
+#endif
240
+	fm_insert_free(qm, f);
241
+}
242
+
243
+
244
+
245
+void fm_status(struct fm_block* qm)
246
+{
247
+	struct fm_frag* f;
248
+	int i,j;
249
+	int h;
250
+
251
+	LOG(L_INFO, "fm_status (%x):\n", qm);
252
+	if (!qm) return;
253
+
254
+	LOG(L_INFO, " heap size= %d\n", qm->size);
255
+#ifdef DBG_F_MALLOC
256
+	LOG(L_INFO, " used= %d, used+overhead=%d, free=%d\n",
257
+			qm->used, qm->real_used, qm->size-qm->real_used);
258
+	LOG(L_INFO, " max used (+overhead)= %d\n", qm->max_real_used);
259
+#endif
260
+	
261
+	LOG(L_INFO, "dumping all fragments:\n");
262
+	for (f=qm->first_frag, i=0;((char*)f<(char*)qm->last_frag) && (i<10);
263
+			f=FRAG_NEXT(f)
264
+			,i++){
265
+		LOG(L_INFO, "    %3d. %c  address=%x  size=%d\n", i, 
266
+				(f->u.reserved)?'a':'N',
267
+				(char*)f+sizeof(struct fm_frag), f->size);
268
+#ifdef DBG_F_MALLOC
269
+		LOG(L_INFO, "            %s from %s: %s(%d)\n",
270
+				(f->u.is_free)?"freed":"alloc'd", f->file, f->func, f->line);
271
+#endif
272
+	}
273
+	LOG(L_INFO, "dumping free list:\n");
274
+	for(h=0,i=0;h<F_HASH_SIZE;h++){
275
+		
276
+		for (f=qm->free_hash[h],j=0; f; f=f->u.nxt_free, i++, j++){
277
+			LOG(L_INFO, "   %5d.[%3d:%3d] %c  address=%x  size=%d(%x)\n",
278
+					i, h, j,
279
+					(f->u.reserved)?'a':'N',
280
+					(char*)f+sizeof(struct fm_frag), f->size, f->size);
281
+#ifdef DBG_F_MALLOC
282
+			DBG("            %s from %s: %s(%d)\n", 
283
+				(f->u.reserved)?"freed":"alloc'd", f->file, f->func, f->line);
284
+#endif
285
+		}
286
+	}
287
+	LOG(L_INFO, "-----------------------------\n");
288
+}
289
+
290
+
291
+
292
+
293
+#endif
0 294
new file mode 100644
... ...
@@ -0,0 +1,83 @@
1
+/* $Id$
2
+ *
3
+ * simple, very fast, & dummy malloc library
4
+ */
5
+
6
+#if !defined(f_malloc_h) && !defined(VQ_MALLOC) 
7
+#define f_malloc_h
8
+
9
+
10
+
11
+/* defs*/
12
+
13
+#define ROUNDTO		8 /* size we round to, must be = 2^n, and
14
+                      sizeof(fm_frag) must be multiple of ROUNDTO !*/
15
+#define MIN_FRAG_SIZE	ROUNDTO
16
+
17
+
18
+
19
+#define F_MALLOC_OPTIMIZE_FACTOR 10 /*used below */
20
+#define F_MALLOC_OPTIMIZE  (1<<F_MALLOC_OPTIMIZE_FACTOR)
21
+								/* size to optimize for,
22
+									(most allocs < this size),
23
+									must be 2^k */
24
+
25
+#define F_HASH_SIZE (F_MALLOC_OPTIMIZE/ROUNDTO + \
26
+		(32-F_MALLOC_OPTIMIZE_FACTOR)+1)
27
+
28
+/* hash structure:
29
+ * 0 .... F_MALLOC_OPTIMIE/ROUNDTO  - small buckets, size increases with
30
+ *                            ROUNDTO from bucket to bucket
31
+ * +1 .... end -  size = 2^k, big buckets */
32
+
33
+struct fm_frag{
34
+	unsigned int size;
35
+	union{
36
+		struct fm_frag* nxt_free;
37
+		int reserved;
38
+	}u;
39
+#ifdef DBG_F_MALLOC
40
+	char* file;
41
+	char* func;
42
+	unsigned int line;
43
+	unsigned int check;
44
+#endif
45
+};
46
+
47
+
48
+struct fm_block{
49
+	unsigned int size; /* total size */
50
+#ifdef DBG_F_MALLOC
51
+	unsigned int used; /* alloc'ed size*/
52
+	unsigned int real_used; /* used+malloc overhead*/
53
+	unsigned int max_real_used;
54
+#endif
55
+	
56
+	struct fm_frag* first_frag;
57
+	struct fm_frag* last_frag;
58
+	
59
+	struct fm_frag* free_hash[F_HASH_SIZE];
60
+};
61
+
62
+
63
+
64
+struct fm_block* fm_malloc_init(char* address, unsigned int size);
65
+
66
+#ifdef DBG_F_MALLOC
67
+void* fm_malloc(struct fm_block*, unsigned int size, char* file, char* func, 
68
+					unsigned int line);
69
+#else
70
+void* fm_malloc(struct fm_block*, unsigned int size);
71
+#endif
72
+
73
+#ifdef DBG_F_MALLOC
74
+void  fm_free(struct fm_block*, void* p, char* file, char* func, 
75
+				unsigned int line);
76
+#else
77
+void  fm_free(struct fm_block*, void* p);
78
+#endif
79
+
80
+void  fm_status(struct fm_block*);
81
+
82
+
83
+#endif