Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,1238 +0,0 @@
1
-/*
2
- * Copyright (C) 2001-2003 FhG Fokus
3
- *
4
- * This file is part of Kamailio, 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
- * \file
21
- * \brief Simple & fast malloc library
22
- * \ingroup mem
23
- */
24
-
25
-
26
-#if defined(Q_MALLOC)
27
-
28
-#include <stdlib.h>
29
-#include <string.h>
30
-
31
-#include "q_malloc.h"
32
-#include "../dprint.h"
33
-#include "../globals.h"
34
-#include "memdbg.h"
35
-#include "../cfg/cfg.h" /* memlog */
36
-#ifdef MALLOC_STATS
37
-#include "../events.h"
38
-#endif
39
-
40
-#include "pkg.h"
41
-
42
-/*useful macros*/
43
-#define FRAG_END(f)  \
44
-	((struct qm_frag_end*)((char*)(f)+sizeof(struct qm_frag)+ \
45
-		(f)->size))
46
-
47
-#define FRAG_NEXT(f) \
48
-	((struct qm_frag*)((char*)(f)+sizeof(struct qm_frag)+(f)->size+ \
49
-		sizeof(struct qm_frag_end)))
50
-
51
-#define FRAG_PREV(f) \
52
-	( (struct qm_frag*) ( ((char*)(f)-sizeof(struct qm_frag_end))- \
53
-	((struct qm_frag_end*)((char*)(f)-sizeof(struct qm_frag_end)))->size- \
54
-		sizeof(struct qm_frag) ) )
55
-
56
-#define PREV_FRAG_END(f) \
57
-	((struct qm_frag_end*)((char*)(f)-sizeof(struct qm_frag_end)))
58
-
59
-
60
-#define FRAG_OVERHEAD	(sizeof(struct qm_frag)+sizeof(struct qm_frag_end))
61
-
62
-
63
-#define ROUNDTO_MASK	(~((unsigned long)ROUNDTO-1))
64
-#define ROUNDUP(s)		(((s)+(ROUNDTO-1))&ROUNDTO_MASK)
65
-#define ROUNDDOWN(s)	((s)&ROUNDTO_MASK)
66
-
67
-
68
-
69
-	/* finds the hash value for s, s=ROUNDTO multiple*/
70
-#define GET_HASH(s)   ( ((unsigned long)(s)<=QM_MALLOC_OPTIMIZE)?\
71
-							(unsigned long)(s)/ROUNDTO: \
72
-							QM_MALLOC_OPTIMIZE/ROUNDTO+big_hash_idx((s))- \
73
-								QM_MALLOC_OPTIMIZE_FACTOR+1 )
74
-
75
-#define UN_HASH(h)	( ((unsigned long)(h)<=(QM_MALLOC_OPTIMIZE/ROUNDTO))?\
76
-							(unsigned long)(h)*ROUNDTO: \
77
-							1UL<<((h)-QM_MALLOC_OPTIMIZE/ROUNDTO+\
78
-								QM_MALLOC_OPTIMIZE_FACTOR-1)\
79
-					)
80
-
81
-
82
-/* mark/test used/unused frags */
83
-#define FRAG_MARK_USED(f)
84
-#define FRAG_CLEAR_USED(f)
85
-#define FRAG_WAS_USED(f)   (1)
86
-
87
-/* other frag related defines:
88
- * MEM_COALESCE_FRAGS
89
- * MEM_FRAG_AVOIDANCE
90
- */
91
-
92
-#define MEM_FRAG_AVOIDANCE
93
-
94
-
95
-/* computes hash number for big buckets*/
96
-inline static unsigned long big_hash_idx(unsigned long s)
97
-{
98
-	int idx;
99
-	/* s is rounded => s = k*2^n (ROUNDTO=2^n)
100
-	 * index= i such that 2^i > s >= 2^(i-1)
101
-	 *
102
-	 * => index = number of the first non null bit in s*/
103
-	idx=sizeof(long)*8-1;
104
-	for (; !(s&(1UL<<(sizeof(long)*8-1))) ; s<<=1, idx--);
105
-	return idx;
106
-}
107
-
108
-
109
-#ifdef DBG_QM_MALLOC
110
-#define ST_CHECK_PATTERN   0xf0f0f0f0
111
-#define END_CHECK_PATTERN1 0xc0c0c0c0
112
-#define END_CHECK_PATTERN2 0xabcdefed
113
-
114
-
115
-static  void qm_debug_frag(struct qm_block* qm, struct qm_frag* f,
116
-		const char* file, unsigned int line)
117
-{
118
-	if (f->check!=ST_CHECK_PATTERN){
119
-		LOG(L_CRIT, "BUG: qm_*: fragm. %p (address %p) "
120
-				"beginning overwritten (%lx)! Memory allocator was called "
121
-				"from %s:%u. Fragment marked by %s:%lu.\n",
122
-				f, (char*)f+sizeof(struct qm_frag),
123
-				f->check, file, line, f->file, f->line);
124
-		qm_status(qm);
125
-		abort();
126
-	};
127
-	if ((FRAG_END(f)->check1!=END_CHECK_PATTERN1)||
128
-		(FRAG_END(f)->check2!=END_CHECK_PATTERN2)){
129
-		LOG(L_CRIT, "BUG: qm_*: fragm. %p (address %p) "
130
-				"end overwritten (%lx, %lx)! Memory allocator was called "
131
-				"from %s:%u. Fragment marked by %s:%lu.\n",
132
-				f, (char*)f+sizeof(struct qm_frag),
133
-				FRAG_END(f)->check1, FRAG_END(f)->check2,
134
-				file, line, f->file, f->line);
135
-		qm_status(qm);
136
-		abort();
137
-	}
138
-	if ((f>qm->first_frag)&&
139
-			((PREV_FRAG_END(f)->check1!=END_CHECK_PATTERN1) ||
140
-				(PREV_FRAG_END(f)->check2!=END_CHECK_PATTERN2) ) ){
141
-		LOG(L_CRIT, "BUG: qm_*: prev. fragm. tail overwritten(%lx, %lx)[%p:%p]! "
142
-				"Memory allocator was called from %s:%u. Fragment marked by "
143
-				"%s:%lu.\n",
144
-				PREV_FRAG_END(f)->check1, PREV_FRAG_END(f)->check2, f,
145
-				(char*)f+sizeof(struct qm_frag), file, line, f->file, f->line);
146
-		qm_status(qm);
147
-		abort();
148
-	}
149
-}
150
-#endif
151
-
152
-
153
-
154
-static inline void qm_insert_free(struct qm_block* qm, struct qm_frag* frag)
155
-{
156
-	struct qm_frag* f;
157
-	struct qm_frag* prev;
158
-	int hash;
159
-
160
-	hash=GET_HASH(frag->size);
161
-	for(f=qm->free_hash[hash].head.u.nxt_free; f!=&(qm->free_hash[hash].head);
162
-			f=f->u.nxt_free){
163
-		if (frag->size <= f->size) break;
164
-	}
165
-	/*insert it here*/
166
-	prev=FRAG_END(f)->prev_free;
167
-	prev->u.nxt_free=frag;
168
-	FRAG_END(frag)->prev_free=prev;
169
-	frag->u.nxt_free=f;
170
-	FRAG_END(f)->prev_free=frag;
171
-	qm->free_hash[hash].no++;
172
-	qm->ffrags++;
173
-}
174
-
175
-
176
-
177
-/* init malloc and return a qm_block*/
178
-struct qm_block* qm_malloc_init(char* address, unsigned long size, int type)
179
-{
180
-	char* start;
181
-	char* end;
182
-	struct qm_block* qm;
183
-	unsigned long init_overhead;
184
-	int h;
185
-
186
-	/* make address and size multiple of 8*/
187
-	start=(char*)ROUNDUP((unsigned long) address);
188
-	DBG("qm_malloc_init: QM_OPTIMIZE=%lu, /ROUNDTO=%lu\n",
189
-			QM_MALLOC_OPTIMIZE, QM_MALLOC_OPTIMIZE/ROUNDTO);
190
-	DBG("qm_malloc_init: QM_HASH_SIZE=%lu, qm_block size=%lu\n",
191
-			QM_HASH_SIZE, (unsigned long)sizeof(struct qm_block));
192
-	DBG("qm_malloc_init(%p, %lu), start=%p\n", address,
193
-			(unsigned long)size, start);
194
-	if (size<start-address) return 0;
195
-	size-=(start-address);
196
-	if (size <(MIN_FRAG_SIZE+FRAG_OVERHEAD)) return 0;
197
-	size=ROUNDDOWN(size);
198
-
199
-	init_overhead=ROUNDUP(sizeof(struct qm_block))+sizeof(struct qm_frag)+
200
-		sizeof(struct qm_frag_end);
201
-	DBG("qm_malloc_init: size= %lu, init_overhead=%lu\n",
202
-			(unsigned long)size, init_overhead);
203
-
204
-	if (size < init_overhead)
205
-	{
206
-		/* not enough mem to create our control structures !!!*/
207
-		LOG(L_ERR, "qm_malloc_init(%lu); No memory left to create control structures!\n",
208
-				(unsigned long)size);
209
-		return 0;
210
-	}
211
-	end=start+size;
212
-	qm=(struct qm_block*)start;
213
-	memset(qm, 0, sizeof(struct qm_block));
214
-	qm->size=size;
215
-	qm->real_used=init_overhead;
216
-	qm->max_real_used=qm->real_used;
217
-	qm->type=type;
218
-	size-=init_overhead;
219
-
220
-	qm->first_frag=(struct qm_frag*)(start+ROUNDUP(sizeof(struct qm_block)));
221
-	qm->last_frag_end=(struct qm_frag_end*)(end-sizeof(struct qm_frag_end));
222
-	/* init initial fragment*/
223
-	qm->first_frag->size=size;
224
-	qm->last_frag_end->size=size;
225
-
226
-#ifdef DBG_QM_MALLOC
227
-	qm->first_frag->check=ST_CHECK_PATTERN;
228
-	qm->last_frag_end->check1=END_CHECK_PATTERN1;
229
-	qm->last_frag_end->check2=END_CHECK_PATTERN2;
230
-#endif
231
-	/* init free_hash* */
232
-	for (h=0; h<QM_HASH_SIZE;h++){
233
-		qm->free_hash[h].head.u.nxt_free=&(qm->free_hash[h].head);
234
-		qm->free_hash[h].tail.prev_free=&(qm->free_hash[h].head);
235
-		qm->free_hash[h].head.size=0;
236
-		qm->free_hash[h].tail.size=0;
237
-	}
238
-
239
-	/* link initial fragment into the free list*/
240
-
241
-	qm_insert_free(qm, qm->first_frag);
242
-
243
-	/*qm->first_frag->u.nxt_free=&(qm->free_lst);
244
-	 * qm->last_frag_end->prev_free=&(qm->free_lst);
245
-	 */
246
-
247
-
248
-	return qm;
249
-}
250
-
251
-
252
-
253
-static inline void qm_detach_free(struct qm_block* qm, struct qm_frag* frag)
254
-{
255
-	struct qm_frag *prev;
256
-	struct qm_frag *next;
257
-
258
-	prev=FRAG_END(frag)->prev_free;
259
-	next=frag->u.nxt_free;
260
-	prev->u.nxt_free=next;
261
-	FRAG_END(next)->prev_free=prev;
262
-}
263
-
264
-
265
-
266
-#ifdef DBG_QM_MALLOC
267
-static inline struct qm_frag* qm_find_free(struct qm_block* qm,
268
-											size_t size,
269
-											int *h,
270
-											unsigned int *count)
271
-#else
272
-static inline struct qm_frag* qm_find_free(struct qm_block* qm,
273
-											size_t size,
274
-											int* h)
275
-#endif
276
-{
277
-	int hash;
278
-	struct qm_frag* f;
279
-
280
-	for (hash=GET_HASH(size); hash<QM_HASH_SIZE; hash++){
281
-		for (f=qm->free_hash[hash].head.u.nxt_free;
282
-					f!=&(qm->free_hash[hash].head); f=f->u.nxt_free){
283
-#ifdef DBG_QM_MALLOC
284
-			*count+=1; /* *count++ generates a warning with gcc 2.9* -Wall */
285
-#endif
286
-			if (f->size>=size){ *h=hash; return f; }
287
-		}
288
-	/*try in a bigger bucket*/
289
-	}
290
-	/* not found */
291
-	LOG(L_ERR, "qm_find_free(%p, %lu); Free fragment not found!\n",
292
-			qm, (unsigned long)size);
293
-	return 0;
294
-}
295
-
296
-
297
-/* returns 0 on success, -1 on error;
298
- * new_size < size & rounded-up already!*/
299
-static inline
300
-#ifdef DBG_QM_MALLOC
301
-int split_frag(struct qm_block* qm, struct qm_frag* f, size_t new_size,
302
-				const char* file, const char* func, unsigned int line, const char *mname)
303
-#else
304
-int split_frag(struct qm_block* qm, struct qm_frag* f, size_t new_size)
305
-#endif
306
-{
307
-	size_t rest;
308
-	struct qm_frag* n;
309
-	struct qm_frag_end* end;
310
-
311
-	rest=f->size-new_size;
312
-#ifdef MEM_FRAG_AVOIDANCE
313
-	if ((rest> (FRAG_OVERHEAD+QM_MALLOC_OPTIMIZE))||
314
-		(rest>=(FRAG_OVERHEAD+new_size))){/* the residue fragm. is big enough*/
315
-#else
316
-	if (rest>(FRAG_OVERHEAD+MIN_FRAG_SIZE)){
317
-#endif
318
-		f->size=new_size;
319
-		/*split the fragment*/
320
-		end=FRAG_END(f);
321
-		end->size=new_size;
322
-		n=(struct qm_frag*)((char*)end+sizeof(struct qm_frag_end));
323
-		n->size=rest-FRAG_OVERHEAD;
324
-		FRAG_END(n)->size=n->size;
325
-		FRAG_CLEAR_USED(n); /* never used */
326
-		qm->real_used+=FRAG_OVERHEAD;
327
-#ifdef DBG_QM_MALLOC
328
-		end->check1=END_CHECK_PATTERN1;
329
-		end->check2=END_CHECK_PATTERN2;
330
-		/* frag created by malloc, mark it*/
331
-		n->file=file;
332
-		n->func=func;
333
-		n->line=line;
334
-		n->mname=mname;
335
-		n->check=ST_CHECK_PATTERN;
336
-#endif
337
-		/* reinsert n in free list*/
338
-		qm_insert_free(qm, n);
339
-		return 0;
340
-	}else{
341
-			/* we cannot split this fragment any more */
342
-		return -1;
343
-	}
344
-}
345
-
346
-
347
-
348
-#ifdef DBG_QM_MALLOC
349
-void* qm_malloc(void* qmp, size_t size,
350
-					const char* file, const char* func, unsigned int line,
351
-					const char *mname)
352
-#else
353
-void* qm_malloc(void* qmp, size_t size)
354
-#endif
355
-{
356
-	struct qm_block* qm;
357
-	struct qm_frag* f;
358
-	int hash;
359
-#ifdef DBG_QM_MALLOC
360
-	unsigned int list_cntr;
361
-#endif
362
-
363
-	qm = (struct qm_block*)qmp;
364
-
365
-#ifdef DBG_QM_MALLOC
366
-	list_cntr = 0;
367
-	MDBG("qm_malloc(%p, %lu) called from %s: %s(%d)\n",
368
-			qm, (unsigned long)size, file, func, line);
369
-#endif
370
-	/*malloc(0) should return a valid pointer according to specs*/
371
-	if(unlikely(size==0)) size=4;
372
-	/*size must be a multiple of 8*/
373
-	size=ROUNDUP(size);
374
-	if (size>(qm->size-qm->real_used)) return 0;
375
-
376
-	/*search for a suitable free frag*/
377
-#ifdef DBG_QM_MALLOC
378
-	if ((f=qm_find_free(qm, size, &hash, &list_cntr))!=0){
379
-#else
380
-	if ((f=qm_find_free(qm, size, &hash))!=0){
381
-#endif
382
-		/* we found it!*/
383
-		/*detach it from the free list*/
384
-#ifdef DBG_QM_MALLOC
385
-			qm_debug_frag(qm, f, file, line);
386
-#endif
387
-		qm_detach_free(qm, f);
388
-		/*mark it as "busy"*/
389
-		f->u.is_free=0;
390
-		qm->free_hash[hash].no--;
391
-		qm->ffrags--;
392
-		/* we ignore split return */
393
-#ifdef DBG_QM_MALLOC
394
-		split_frag(qm, f, size, file, "fragm. from qm_malloc", line, mname);
395
-#else
396
-		split_frag(qm, f, size);
397
-#endif
398
-		qm->real_used+=f->size;
399
-		qm->used+=f->size;
400
-		if (qm->max_real_used<qm->real_used)
401
-			qm->max_real_used=qm->real_used;
402
-#ifdef DBG_QM_MALLOC
403
-		f->file=file;
404
-		f->func=func;
405
-		f->mname=mname;
406
-		f->line=line;
407
-		f->check=ST_CHECK_PATTERN;
408
-		/*  FRAG_END(f)->check1=END_CHECK_PATTERN1;
409
-			FRAG_END(f)->check2=END_CHECK_PATTERN2;*/
410
-		MDBG("qm_malloc(%p, %lu) returns address %p frag. %p (size=%lu) on %d"
411
-				" -th hit\n",
412
-				qm, (unsigned long)size, (char*)f+sizeof(struct qm_frag), f,
413
-				f->size, list_cntr);
414
-#endif
415
-#ifdef MALLOC_STATS
416
-		if(qm->type==MEM_TYPE_PKG) {
417
-			sr_event_exec(SREV_PKG_UPDATE_STATS, 0);
418
-		}
419
-#endif
420
-		return (char*)f+sizeof(struct qm_frag);
421
-	}
422
-
423
-#ifdef DBG_QM_MALLOC
424
-	LOG(L_ERR, "qm_malloc(%p, %lu) called from %s: %s(%d), module: %s; Free fragment not found!\n",
425
-			qm, (unsigned long)size, file, func, line, mname);
426
-#else
427
-	LOG(L_ERR, "qm_malloc(%p, %lu); Free fragment not found!\n",
428
-			qm, (unsigned long)size);
429
-#endif
430
-
431
-	return 0;
432
-}
433
-
434
-
435
-
436
-#ifdef DBG_QM_MALLOC
437
-void qm_free(void* qmp, void* p, const char* file, const char* func,
438
-				unsigned int line, const char *mname)
439
-#else
440
-void qm_free(void* qmp, void* p)
441
-#endif
442
-{
443
-	struct qm_block* qm;
444
-	struct qm_frag* f;
445
-	size_t size;
446
-#ifdef MEM_JOIN_FREE
447
-	struct qm_frag* next;
448
-	struct qm_frag* prev;
449
-#endif /* MEM_JOIN_FREE*/
450
-
451
-	qm = (struct qm_block*)qmp;
452
-
453
-#ifdef DBG_QM_MALLOC
454
-	MDBG("qm_free(%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line);
455
-#endif
456
-
457
-	if (p==0) {
458
-#ifdef DBG_QM_MALLOC
459
-		LOG(L_WARN, "WARNING:qm_free: free(0) called from %s: %s(%d)\n", file, func, line);
460
-#else
461
-		LOG(L_WARN, "WARNING:qm_free: free(0) called\n");
462
-#endif
463
-		return;
464
-	}
465
-
466
-#ifdef DBG_QM_MALLOC
467
-	if (p>(void*)qm->last_frag_end || p<(void*)qm->first_frag){
468
-		LOG(L_CRIT, "BUG: qm_free: bad pointer %p (out of memory block!)"
469
-				" called from %s: %s(%d) - aborting\n", p, file, func, line);
470
-		if(likely(cfg_get(core, core_cfg, mem_safety)==0))
471
-			abort();
472
-		else return;
473
-	}
474
-#endif
475
-
476
-	f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag));
477
-
478
-#ifdef DBG_QM_MALLOC
479
-	qm_debug_frag(qm, f, file, line);
480
-	if (f->u.is_free){
481
-		LOG(L_CRIT, "BUG: qm_free: freeing already freed pointer (%p),"
482
-				" called from %s: %s(%d), first free %s: %s(%ld) - aborting\n",
483
-				p, file, func, line, f->file, f->func, f->line);
484
-		if(likely(cfg_get(core, core_cfg, mem_safety)==0))
485
-			abort();
486
-		else return;
487
-	}
488
-	MDBG("qm_free: freeing frag. %p alloc'ed from %s: %s(%ld)\n",
489
-			f, f->file, f->func, f->line);
490
-#endif
491
-	if (unlikely(f->u.is_free)){
492
-		LM_INFO("freeing a free fragment (%p/%p) - ignore\n",
493
-				f, p);
494
-		return;
495
-	}
496
-
497
-	size=f->size;
498
-	qm->used-=size;
499
-	qm->real_used-=size;
500
-
501
-#ifdef MEM_JOIN_FREE
502
-	if(unlikely(cfg_get(core, core_cfg, mem_join)!=0)) {
503
-		next=prev=0;
504
-		/* mark this fragment as used (might fall into the middle of joined frags)
505
-		 * to give us an extra chance of detecting a double free call (if the joined
506
-		 * fragment has not yet been reused) */
507
-		f->u.nxt_free=(void*)0x1L; /* bogus value, just to mark it as free */
508
-		/* join packets if possible*/
509
-		next=FRAG_NEXT(f);
510
-		if (((char*)next < (char*)qm->last_frag_end) && (next->u.is_free)){
511
-			/* join next packet */
512
-#ifdef DBG_QM_MALLOC
513
-			qm_debug_frag(qm, next, file, line);
514
-#endif
515
-			qm_detach_free(qm, next);
516
-			size+=next->size+FRAG_OVERHEAD;
517
-			qm->real_used-=FRAG_OVERHEAD;
518
-			qm->free_hash[GET_HASH(next->size)].no--; /* FIXME slow */
519
-			qm->ffrags--;
520
-		}
521
-
522
-		if (f > qm->first_frag){
523
-			prev=FRAG_PREV(f);
524
-			/*	(struct qm_frag*)((char*)f - (struct qm_frag_end*)((char*)f-
525
-								sizeof(struct qm_frag_end))->size);*/
526
-			if (prev->u.is_free){
527
-				/* join prev packet */
528
-#ifdef DBG_QM_MALLOC
529
-				qm_debug_frag(qm, prev, file, line);
530
-#endif
531
-				qm_detach_free(qm, prev);
532
-				size+=prev->size+FRAG_OVERHEAD;
533
-				qm->real_used-=FRAG_OVERHEAD;
534
-				qm->free_hash[GET_HASH(prev->size)].no--; /* FIXME slow */
535
-				qm->ffrags--;
536
-				f=prev;
537
-			}
538
-		}
539
-		f->size=size;
540
-		FRAG_END(f)->size=f->size;
541
-	} /* if cfg_core->mem_join */
542
-#endif /* MEM_JOIN_FREE*/
543
-#ifdef DBG_QM_MALLOC
544
-	f->file=file;
545
-	f->func=func;
546
-	f->mname=mname;
547
-	f->line=line;
548
-#endif
549
-	qm_insert_free(qm, f);
550
-#ifdef MALLOC_STATS
551
-	if(qm->type==MEM_TYPE_PKG) {
552
-		sr_event_exec(SREV_PKG_UPDATE_STATS, 0);
553
-	}
554
-#endif
555
-}
556
-
557
-
558
-
559
-#ifdef DBG_QM_MALLOC
560
-void* qm_realloc(void* qmp, void* p, size_t size,
561
-					const char* file, const char* func, unsigned int line,
562
-					const char *mname)
563
-#else
564
-void* qm_realloc(void* qmp, void* p, size_t size)
565
-#endif
566
-{
567
-	struct qm_block* qm;
568
-	struct qm_frag* f;
569
-	size_t diff;
570
-	size_t orig_size;
571
-	struct qm_frag* n;
572
-	void* ptr;
573
-
574
-	qm = (struct qm_block*)qmp;
575
-
576
-#ifdef DBG_QM_MALLOC
577
-	MDBG("qm_realloc(%p, %p, %lu) called from %s: %s(%d)\n",
578
-			qm, p, (unsigned long)size,
579
-			file, func, line);
580
-	if ((p)&&(p>(void*)qm->last_frag_end || p<(void*)qm->first_frag)){
581
-		LOG(L_CRIT, "BUG: qm_free: bad pointer %p (out of memory block!) - "
582
-				"aborting\n", p);
583
-		abort();
584
-	}
585
-#endif
586
-
587
-	if (size==0) {
588
-		if (p)
589
-#ifdef DBG_QM_MALLOC
590
-			qm_free(qm, p, file, func, line, mname);
591
-#else
592
-			qm_free(qm, p);
593
-#endif
594
-		return 0;
595
-	}
596
-	if (p==0)
597
-#ifdef DBG_QM_MALLOC
598
-		return qm_malloc(qm, size, file, func, line, mname);
599
-#else
600
-		return qm_malloc(qm, size);
601
-#endif
602
-	f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag));
603
-#ifdef DBG_QM_MALLOC
604
-	qm_debug_frag(qm, f, file, line);
605
-	MDBG("qm_realloc: realloc'ing frag %p alloc'ed from %s: %s(%ld)\n",
606
-			f, f->file, f->func, f->line);
607
-	if (f->u.is_free){
608
-		LOG(L_CRIT, "BUG:qm_realloc: trying to realloc an already freed "
609
-				"pointer %p , fragment %p -- aborting\n", p, f);
610
-		abort();
611
-	}
612
-#endif
613
-	/* find first acceptable size */
614
-	size=ROUNDUP(size);
615
-	if (f->size > size){
616
-		orig_size=f->size;
617
-		/* shrink */
618
-#ifdef DBG_QM_MALLOC
619
-		MDBG("qm_realloc: shrinking from %lu to %lu\n",
620
-				f->size, (unsigned long)size);
621
-		if(split_frag(qm, f, size, file, "fragm. from qm_realloc", line, mname)!=0){
622
-		MDBG("qm_realloc : shrinked successful\n");
623
-#else
624
-		if(split_frag(qm, f, size)!=0){
625
-#endif
626
-			/* update used sizes: freed the splited frag */
627
-			/* split frag already adds FRAG_OVERHEAD for the newly created
628
-			 * free frag, so here we only need orig_size-f->size for real used
629
-			 */
630
-			qm->real_used-=(orig_size-f->size);
631
-			qm->used-=(orig_size-f->size);
632
-		}
633
-
634
-	}else if (f->size < size){
635
-		/* grow */
636
-#ifdef DBG_QM_MALLOC
637
-		MDBG("qm_realloc: growing from %lu to %lu\n",
638
-				f->size, (unsigned long)size);
639
-#endif
640
-			orig_size=f->size;
641
-			diff=size-f->size;
642
-			n=FRAG_NEXT(f);
643
-			if (((char*)n < (char*)qm->last_frag_end) &&
644
-					(n->u.is_free)&&((n->size+FRAG_OVERHEAD)>=diff)){
645
-				/* join  */
646
-				qm_detach_free(qm, n);
647
-				qm->free_hash[GET_HASH(n->size)].no--; /*FIXME: slow*/
648
-				qm->ffrags--;
649
-				f->size+=n->size+FRAG_OVERHEAD;
650
-				qm->real_used-=FRAG_OVERHEAD;
651
-				FRAG_END(f)->size=f->size;
652
-				/* end checks should be ok */
653
-				/* split it if necessary */
654
-				if (f->size > size ){
655
-	#ifdef DBG_QM_MALLOC
656
-					split_frag(qm, f, size, file, "fragm. from qm_realloc",
657
-										line, mname);
658
-	#else
659
-					split_frag(qm, f, size);
660
-	#endif
661
-				}
662
-				qm->real_used+=(f->size-orig_size);
663
-				qm->used+=(f->size-orig_size);
664
-			}else{
665
-				/* could not join => realloc */
666
-	#ifdef DBG_QM_MALLOC
667
-				ptr=qm_malloc(qm, size, file, func, line, mname);
668
-	#else
669
-				ptr=qm_malloc(qm, size);
670
-	#endif
671
-				if (ptr){
672
-					/* copy, need by libssl */
673
-					memcpy(ptr, p, orig_size);
674
-				} else {
675
-#ifdef DBG_QM_MALLOC
676
-					LOG(L_ERR, "qm_realloc(%p, %lu) called from %s: %s(%d), module: %s; qm_malloc() failed!\n",
677
-							qm, (unsigned long)size, file, func, line, mname);
678
-#else
679
-					LOG(L_ERR, "qm_realloc(%p, %lu); qm_malloc() failed!\n",
680
-							qm, (unsigned long)size);
681
-#endif
682
-				}
683
-	#ifdef DBG_QM_MALLOC
684
-				qm_free(qm, p, file, func, line, mname);
685
-	#else
686
-				qm_free(qm, p);
687
-	#endif
688
-				p=ptr;
689
-			}
690
-	}else{
691
-		/* do nothing */
692
-#ifdef DBG_QM_MALLOC
693
-		MDBG("qm_realloc: doing nothing, same size: %lu - %lu\n",
694
-				f->size, (unsigned long)size);
695
-#endif
696
-	}
697
-#ifdef DBG_QM_MALLOC
698
-	MDBG("qm_realloc: returning %p\n", p);
699
-#endif
700
-#ifdef MALLOC_STATS
701
-	if(qm->type==MEM_TYPE_PKG) {
702
-		sr_event_exec(SREV_PKG_UPDATE_STATS, 0);
703
-	}
704
-#endif
705
-	return p;
706
-}
707
-
708
-
709
-void qm_check(struct qm_block* qm)
710
-{
711
-	struct qm_frag* f;
712
-	long fcount = 0;
713
-	int memlog;
714
-
715
-	memlog=cfg_get(core, core_cfg, memlog);
716
-	LOG(memlog, "DEBUG: qm_check()\n");
717
-	f = qm->first_frag;
718
-	while ((char*)f < (char*)qm->last_frag_end) {
719
-		fcount++;
720
-		/* check struct qm_frag */
721
-#ifdef DBG_QM_MALLOC
722
-		if (f->check!=ST_CHECK_PATTERN){
723
-			LOG(L_CRIT, "BUG: qm_*: fragm. %p (address %p) "
724
-					"beginning overwritten(%lx)!\n",
725
-					f, (char*)f + sizeof(struct qm_frag),
726
-					f->check);
727
-			qm_status(qm);
728
-			abort();
729
-		};
730
-#endif
731
-		if (f + sizeof(struct qm_frag) + f->size + sizeof(struct qm_frag_end) > qm->first_frag + qm->size) {
732
-			LOG(L_CRIT, "BUG: qm_*: fragm. %p (address %p) "
733
-				"bad size: %lu (frag end: %p > end of block: %p)\n",
734
-				f, (char*)f + sizeof(struct qm_frag) + sizeof(struct qm_frag_end), f->size,
735
-				f + sizeof(struct qm_frag) + f->size, qm->first_frag + qm->size);
736
-			qm_status(qm);
737
-			abort();
738
-		}
739
-		/* check struct qm_frag_end */
740
-		if (FRAG_END(f)->size != f->size) {
741
-			LOG(L_CRIT, "BUG: qm_*: fragm. %p (address %p) "
742
-				"size in qm_frag and qm_frag_end does not match: frag->size=%lu, frag_end->size=%lu)\n",
743
-				f, (char*)f + sizeof(struct qm_frag),
744
-				f->size, FRAG_END(f)->size);
745
-			qm_status(qm);
746
-			abort();
747
-		}
748
-#ifdef DBG_QM_MALLOC
749
-		if ((FRAG_END(f)->check1 != END_CHECK_PATTERN1) ||
750
-			(FRAG_END(f)->check2 != END_CHECK_PATTERN2)) {
751
-			LOG(L_CRIT, "BUG: qm_*: fragm. %p (address %p)"
752
-						" end overwritten(%lx, %lx)!\n",
753
-					f, (char*)f + sizeof(struct qm_frag),
754
-					FRAG_END(f)->check1, FRAG_END(f)->check2);
755
-			qm_status(qm);
756
-			abort();
757
-		}
758
-#endif
759
-		f = FRAG_NEXT(f);
760
-	}
761
-
762
-	LOG(memlog, "DEBUG: qm_check: %lu fragments OK\n", fcount);
763
-}
764
-
765
-void qm_status(void* qmp)
766
-{
767
-	struct qm_block* qm;
768
-	struct qm_frag* f;
769
-	int i,j;
770
-	int h;
771
-	int unused;
772
-	int memlog;
773
-	int mem_summary;
774
-
775
-	qm = (struct qm_block*)qmp;
776
-
777
-	memlog=cfg_get(core, core_cfg, memlog);
778
-	mem_summary=cfg_get(core, core_cfg, mem_summary);
779
-	LOG_(DEFAULT_FACILITY, memlog, "qm_status: ", "(%p):\n", qm);
780
-	if (!qm) return;
781
-
782
-	LOG_(DEFAULT_FACILITY, memlog, "qm_status: ", "heap size= %lu\n",
783
-			qm->size);
784
-	LOG_(DEFAULT_FACILITY, memlog, "qm_status: ",
785
-			"used= %lu, used+overhead=%lu, free=%lu\n",
786
-			qm->used, qm->real_used, qm->size-qm->real_used);
787
-	LOG_(DEFAULT_FACILITY, memlog, "qm_status: ",
788
-			"max used (+overhead)= %lu\n", qm->max_real_used);
789
-
790
-	if (mem_summary & 16) return;
791
-
792
-	LOG_(DEFAULT_FACILITY, memlog, "qm_status: ",
793
-			"dumping all alloc'ed. fragments:\n");
794
-	for (f=qm->first_frag, i=0;(char*)f<(char*)qm->last_frag_end;f=FRAG_NEXT(f)
795
-			,i++){
796
-		if ((! f->u.is_free) || (cfg_get(core, core_cfg, mem_status_mode)!=0)){
797
-			LOG_(DEFAULT_FACILITY, memlog, "qm_status: ",
798
-					"   %3d. %c  address=%p frag=%p size=%lu used=%d\n",
799
-				i,
800
-				(f->u.is_free)?'A':'N',
801
-				(char*)f+sizeof(struct qm_frag), f, f->size, FRAG_WAS_USED(f));
802
-#ifdef DBG_QM_MALLOC
803
-			LOG_(DEFAULT_FACILITY, memlog, "qm_status: ",
804
-					"          %s from %s: %s(%ld)\n",
805
-				(f->u.is_free)?"freed":"alloc'd", f->file, f->func, f->line);
806
-			LOG_(DEFAULT_FACILITY, memlog, "qm_status: ",
807
-					"         start check=%lx, end check= %lx, %lx\n",
808
-				f->check, FRAG_END(f)->check1, FRAG_END(f)->check2);
809
-			if (f->check!=ST_CHECK_PATTERN){
810
-				LOG_(DEFAULT_FACILITY, memlog, "qm_status: ",
811
-						"         * beginning overwritten(%lx)!\n",
812
-						f->check);
813
-			}
814
-			if ((FRAG_END(f)->check1 != END_CHECK_PATTERN1)
815
-					|| (FRAG_END(f)->check2 != END_CHECK_PATTERN2)) {
816
-				LOG_(DEFAULT_FACILITY, memlog, "qm_status: ",
817
-						"         * end overwritten(%lx, %lx)!\n",
818
-						FRAG_END(f)->check1, FRAG_END(f)->check2);
819
-			}
820
-
821
-#endif
822
-		}
823
-	}
824
-	LOG_(DEFAULT_FACILITY, memlog, "qm_status: ",
825
-			"dumping free list stats :\n");
826
-	for(h=0,i=0;h<QM_HASH_SIZE;h++){
827
-		unused=0;
828
-		for (f=qm->free_hash[h].head.u.nxt_free,j=0;
829
-				f!=&(qm->free_hash[h].head); f=f->u.nxt_free, i++, j++){
830
-				if (!FRAG_WAS_USED(f)){
831
-					unused++;
832
-#ifdef DBG_QM_MALLOC
833
-					LOG_(DEFAULT_FACILITY, memlog, "qm_status: ",
834
-						"unused fragm.: hash = %3d, fragment %p,"
835
-						" address %p size %lu, created from %s: %s(%lu)\n",
836
-						h, f, (char*)f+sizeof(struct qm_frag), f->size,
837
-						f->file, f->func, f->line);
838
-#endif
839
-				}
840
-		}
841
-
842
-		if (j) LOG_(DEFAULT_FACILITY, memlog, "qm_status: ",
843
-				"hash= %3d. fragments no.: %5d, unused: %5d\n"
844
-					"\t\t bucket size: %9lu - %9ld (first %9lu)\n",
845
-					h, j, unused, UN_HASH(h),
846
-					((h<=QM_MALLOC_OPTIMIZE/ROUNDTO)?1:2)*UN_HASH(h),
847
-					qm->free_hash[h].head.u.nxt_free->size
848
-				);
849
-		if (j!=qm->free_hash[h].no){
850
-			LOG(L_CRIT, "BUG: qm_status: different free frag. count: %d!=%lu"
851
-				" for hash %3d\n", j, qm->free_hash[h].no, h);
852
-		}
853
-
854
-	}
855
-	LOG_(DEFAULT_FACILITY, memlog, "qm_status: ",
856
-			"-----------------------------\n");
857
-}
858
-
859
-
860
-/* fills a malloc info structure with info about the block
861
- * if a parameter is not supported, it will be filled with 0 */
862
-void qm_info(void* qmp, struct mem_info* info)
863
-{
864
-	struct qm_block* qm;
865
-
866
-	qm = (struct qm_block*)qmp;
867
-
868
-	memset(info,0, sizeof(*info));
869
-	info->total_size=qm->size;
870
-	info->min_frag=MIN_FRAG_SIZE;
871
-	info->free=qm->size-qm->real_used;
872
-	info->used=qm->used;
873
-	info->real_used=qm->real_used;
874
-	info->max_used=qm->max_real_used;
875
-	info->total_frags=qm->ffrags;
876
-}
877
-
878
-
879
-/* returns how much free memory is available
880
- * it never returns an error (unlike fm_available) */
881
-unsigned long qm_available(void* qmp)
882
-{
883
-	struct qm_block* qm;
884
-
885
-	qm = (struct qm_block*)qmp;
886
-
887
-	return qm->size-qm->real_used;
888
-}
889
-
890
-
891
-
892
-#ifdef DBG_QM_MALLOC
893
-
894
-
895
-static mem_counter* get_mem_counter(mem_counter **root, struct qm_frag* f)
896
-{
897
-	mem_counter *x;
898
-	if (!*root) goto make_new;
899
-	for(x=*root;x;x=x->next)
900
-		if (x->file == f->file && x->func == f->func && x->line == f->line)
901
-			return x;
902
-make_new:
903
-	x = malloc(sizeof(mem_counter));