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