Browse code

- re-enabled locking in shm_status() - added fifo meminfo commands: serctl fifo meminfo total:33340380 free:33112744 used:227636 max used:227636 fragments:1

(where used = allocated shm mem + overhead)

Andrei Pelinescu-Onciul authored on 02/03/2005 11:45:12
Showing 9 changed files
... ...
@@ -53,7 +53,7 @@ MAIN_NAME=ser
53 53
 VERSION = 0
54 54
 PATCHLEVEL = 10
55 55
 SUBLEVEL =   99
56
-EXTRAVERSION = -dev2
56
+EXTRAVERSION = -dev3
57 57
 
58 58
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
59 59
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
... ...
@@ -64,6 +64,7 @@
64 64
  *  2004-04-29  added chown(sock_user, sock_group)  (andrei)
65 65
  *  2004-06-06  updated to the new DB interface  & init_db_fifo (andrei)
66 66
  *  2004-09-19  fifo is deleted on exit (destroy_fifo)  (andrei)
67
+ *  2005-03-02  meminfo fifo cmd added (andrei)
67 68
  */
68 69
 
69 70
 
... ...
@@ -90,6 +91,7 @@
90 90
 #include "globals.h"
91 91
 #include "fifo_server.h"
92 92
 #include "mem/mem.h"
93
+#include "mem/shm_mem.h" /* shm_info() */
93 94
 #include "sr_module.h"
94 95
 #include "pt.h"
95 96
 #include "db/db_fifo.h"
... ...
@@ -868,6 +870,35 @@ static int ps_fifo_cmd(FILE *stream, char *response_file )
868 868
 }
869 869
 
870 870
 
871
+
872
+static int meminfo_fifo_cmd( FILE *stream, char *response_file )
873
+{
874
+	struct meminfo mi;
875
+	
876
+	if (response_file==0 || *response_file==0 ) { 
877
+		LOG(L_ERR, "ERROR: meminfo_fifo_cmd: null file\n");
878
+		return -1;
879
+	}
880
+	
881
+#ifdef SHM_MEM
882
+	shm_info(&mi);
883
+	fifo_reply( response_file, "200 ok\n"
884
+					"total:%ld\n"
885
+					"free:%ld\n"
886
+					"used:%ld\n"
887
+					"max used:%ld\n"
888
+					"fragments:%ld\n",
889
+					mi.total_size, mi.free, mi.real_used,
890
+					mi.max_used, mi.total_frags);
891
+#else
892
+	fifo_reply( response_file, "400 No shared memory support\n");
893
+#endif
894
+
895
+	return 1;
896
+}
897
+
898
+
899
+
871 900
 int register_core_fifo()
872 901
 {
873 902
 	if (register_fifo_cmd(print_fifo_cmd, FIFO_PRINT, 0)<0) {
... ...
@@ -902,6 +933,10 @@ int register_core_fifo()
902 902
 		LOG(L_CRIT, "ERROR: unable to register '%s' FIFO cmd\n", FIFO_KILL);
903 903
 		return -1;
904 904
 	}
905
+	if (register_fifo_cmd(meminfo_fifo_cmd, FIFO_MEMINFO, 0)<0) {
906
+		LOG(L_CRIT, "ERROR: unable to register '%s' FIFO cmd\n", FIFO_MEMINFO);
907
+		return -1;
908
+	}
905 909
 	if (fifo_db_url==0) {
906 910
 		LOG(L_WARN,"WARNING: no fifo_db_url given - "
907 911
 			"fifo DB commands disabled!\n");
... ...
@@ -51,6 +51,7 @@
51 51
 #define FIFO_PWD "pwd"
52 52
 /* kill the server */
53 53
 #define FIFO_KILL "kill"
54
+#define FIFO_MEMINFO "meminfo"
54 55
 
55 56
 #define MAX_CTIME_LEN 128
56 57
 
... ...
@@ -33,6 +33,7 @@
33 33
  *               memory blocks (64 bits machine & size >=2^32) 
34 34
  *              GET_HASH s/</<=/ (avoids waste of 1 hash cell)   (andrei)
35 35
  *  2004-11-10  support for > 4Gb mem., switched to long (andrei)
36
+ *  2005-03-02  added fm_info() (andrei)
36 37
  */
37 38
 
38 39
 
... ...
@@ -161,8 +162,10 @@ void fm_split_frag(struct fm_block* qm, struct fm_frag* frag,
161 161
 		n=FRAG_NEXT(frag);
162 162
 		n->size=rest-FRAG_OVERHEAD;
163 163
 		FRAG_CLEAR_USED(n); /* never used */
164
-#ifdef DBG_F_MALLOC
164
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
165 165
 		qm->real_used+=FRAG_OVERHEAD;
166
+#endif
167
+#ifdef DBG_F_MALLOC
166 168
 		/* frag created by malloc, mark it*/
167 169
 		n->file=file;
168 170
 		n->func="frag. from fm_malloc";
... ...
@@ -206,7 +209,7 @@ struct fm_block* fm_malloc_init(char* address, unsigned long size)
206 206
 	memset(qm, 0, sizeof(struct fm_block));
207 207
 	size-=init_overhead;
208 208
 	qm->size=size;
209
-#ifdef DBG_F_MALLOC
209
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
210 210
 	qm->real_used=init_overhead;
211 211
 	qm->max_real_used=qm->real_used;
212 212
 #endif
... ...
@@ -275,11 +278,6 @@ found:
275 275
 	
276 276
 #ifdef DBG_F_MALLOC
277 277
 	fm_split_frag(qm, frag, size, file, func, line);
278
-	qm->real_used+=frag->size;
279
-	qm->used+=frag->size;
280
-
281
-	if (qm->max_real_used<qm->real_used)
282
-		qm->max_real_used=qm->real_used;
283 278
 
284 279
 	frag->file=file;
285 280
 	frag->func=func;
... ...
@@ -290,6 +288,12 @@ found:
290 290
 #else
291 291
 	fm_split_frag(qm, frag, size);
292 292
 #endif
293
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
294
+	qm->real_used+=frag->size;
295
+	qm->used+=frag->size;
296
+	if (qm->max_real_used<qm->real_used)
297
+		qm->max_real_used=qm->real_used;
298
+#endif
293 299
 	FRAG_MARK_USED(frag); /* mark it as used */
294 300
 	return (char*)frag+sizeof(struct fm_frag);
295 301
 }
... ...
@@ -324,10 +328,11 @@ void fm_free(struct fm_block* qm, void* p)
324 324
 			f->line);
325 325
 #endif
326 326
 	size=f->size;
327
-
328
-#ifdef DBG_F_MALLOC
327
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
329 328
 	qm->used-=size;
330 329
 	qm->real_used-=size;
330
+#endif
331
+#ifdef DBG_F_MALLOC
331 332
 	f->file=file;
332 333
 	f->func=func;
333 334
 	f->line=line;
... ...
@@ -387,11 +392,13 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size)
387 387
 #ifdef DBG_F_MALLOC
388 388
 		DBG("fm_realloc: shrinking from %lu to %lu\n", f->size, size);
389 389
 		fm_split_frag(qm, f, size, file, "frag. from fm_realloc", line);
390
-		qm->real_used-=(orig_size-f->size);
391
-		qm->used-=(orig_size-f->size);
392 390
 #else
393 391
 		fm_split_frag(qm, f, size);
394 392
 #endif
393
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
394
+		qm->real_used-=(orig_size-f->size);
395
+		qm->used-=(orig_size-f->size);
396
+#endif
395 397
 	}else if (f->size<size){
396 398
 		/* grow */
397 399
 #ifdef DBG_F_MALLOC
... ...
@@ -418,7 +425,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size)
418 418
 			qm->free_hash[hash].no--;
419 419
 			/* join */
420 420
 			f->size+=n->size+FRAG_OVERHEAD;
421
-		#ifdef DBG_F_MALLOC
421
+		#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
422 422
 			qm->real_used-=FRAG_OVERHEAD;
423 423
 		#endif
424 424
 			/* split it if necessary */
... ...
@@ -430,7 +437,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size)
430 430
 				fm_split_frag(qm, f, size);
431 431
 		#endif
432 432
 			}
433
-		#ifdef DBG_F_MALLOC
433
+		#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
434 434
 			qm->real_used+=(f->size-orig_size);
435 435
 			qm->used+=(f->size-orig_size);
436 436
 		#endif
... ...
@@ -478,7 +485,7 @@ void fm_status(struct fm_block* qm)
478 478
 	if (!qm) return;
479 479
 
480 480
 	LOG(memlog, " heap size= %ld\n", qm->size);
481
-#ifdef DBG_F_MALLOC
481
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
482 482
 	LOG(memlog, " used= %lu, used+overhead=%lu, free=%lu\n",
483 483
 			qm->used, qm->real_used, qm->size-qm->real_used);
484 484
 	LOG(memlog, " max used (+overhead)= %lu\n", qm->max_real_used);
... ...
@@ -540,5 +547,46 @@ void fm_status(struct fm_block* qm)
540 540
 
541 541
 
542 542
 
543
+/* fills a malloc info structure with info about the block
544
+ * if a parameter is not supported, it will be filled with 0 */
545
+void fm_info(struct fm_block* qm, struct meminfo* info)
546
+{
547
+	int r;
548
+	long total_frags;
549
+#if !defined(DBG_F_MALLOC) && !defined(MALLOC_STATS)
550
+	struct fm_frag* f;
551
+#endif
552
+	
553
+	memset(info,0, sizeof(*info));
554
+	total_frags=0;
555
+	info->total_size=qm->size;
556
+	info->min_frag=MIN_FRAG_SIZE;
557
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
558
+	info->free=qm->size-qm->real_used;
559
+	info->used=qm->used;
560
+	info->real_used=qm->real_used;
561
+	info->max_used=qm->max_real_used;
562
+	for(r=0;r<F_HASH_SIZE; r++){
563
+		total_frags+=qm->free_hash[r].no;
564
+	}
565
+#else
566
+	/* we'll have to compute it all */
567
+	for (r=0; r<=F_MALLOC_OPTIMIZE/ROUNDTO; r++){
568
+		info->free+=qm->free_hash[r].no*UN_HASH(r);
569
+		total_frags+=qm->free_hash[r].no;
570
+	}
571
+	for(;r<F_HASH_SIZE; r++){
572
+		total_frags+=qm->free_hash[r].no;
573
+		for(f=qm->free_hash[r].first;f;f=f->u.nxt_free){
574
+			info->free+=f->size;
575
+		}
576
+	}
577
+	info->real_used=info->total_size-info->free;
578
+	info->used=0; /* we don't really now */
579
+	info->max_used=0; /* we don't really now */
580
+#endif
581
+	info->total_frags=total_frags;
582
+}
583
+
543 584
 
544 585
 #endif
... ...
@@ -39,7 +39,11 @@
39 39
 #if !defined(f_malloc_h) && !defined(VQ_MALLOC) 
40 40
 #define f_malloc_h
41 41
 
42
+#ifdef DBG_QM_MALLOC
43
+#define DBG_F_MALLOC
44
+#endif
42 45
 
46
+#include "meminfo.h"
43 47
 
44 48
 /* defs*/
45 49
 
... ...
@@ -95,7 +99,7 @@ struct fm_frag_lnk{
95 95
 
96 96
 struct fm_block{
97 97
 	unsigned long size; /* total size */
98
-#ifdef DBG_F_MALLOC
98
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
99 99
 	unsigned long used; /* alloc'ed size*/
100 100
 	unsigned long real_used; /* used+malloc overhead*/
101 101
 	unsigned long max_real_used;
... ...
@@ -133,6 +137,7 @@ void*  fm_realloc(struct fm_block*, void* p, unsigned long size);
133 133
 #endif
134 134
 
135 135
 void  fm_status(struct fm_block*);
136
+void  fm_info(struct fm_block*, struct meminfo*);
136 137
 
137 138
 
138 139
 #endif
139 140
new file mode 100644
... ...
@@ -0,0 +1,48 @@
0
+/* $Id$*
1
+ *
2
+ * mem (malloc) info 
3
+ *
4
+ * Copyright (C) 2001-2003 FhG Fokus
5
+ *
6
+ * This file is part of ser, a free SIP server.
7
+ *
8
+ * ser is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * For a license to use the ser software under conditions
14
+ * other than those described here, or to purchase support for this
15
+ * software, please contact iptel.org by e-mail at the following addresses:
16
+ *    info@iptel.org
17
+ *
18
+ * ser is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License 
24
+ * along with this program; if not, write to the Free Software 
25
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
+ */
27
+/*
28
+ * History:
29
+ * --------
30
+ *  2005-03-02  created (andrei)
31
+ */
32
+
33
+#ifndef meminfo_h
34
+#define meminfo_h
35
+
36
+struct meminfo{
37
+	unsigned long total_size;
38
+	unsigned long free;
39
+	unsigned long used;
40
+	unsigned long real_used; /*used + overhead*/
41
+	unsigned long max_used;
42
+	unsigned long min_frag;
43
+	unsigned long total_frags; /* total fragment no */
44
+};
45
+
46
+#endif
47
+
... ...
@@ -34,6 +34,7 @@
34 34
  *               memory blocks (64 bits machine & size>=2^32) (andrei)
35 35
  *              GET_HASH s/</<=/ (avoids waste of 1 hash cell) (andrei)
36 36
  *  2004-11-10  support for > 4Gb mem., switched to long (andrei)
37
+ *  2005-03-02  added qm_info() (andrei)
37 38
  */
38 39
 
39 40
 
... ...
@@ -684,6 +685,27 @@ void qm_status(struct qm_block* qm)
684 684
 }
685 685
 
686 686
 
687
+/* fills a malloc info structure with info about the block
688
+ * if a parameter is not supported, it will be filled with 0 */
689
+void qm_info(struct qm_block* qm, struct meminfo* info)
690
+{
691
+	int r;
692
+	long total_frags;
693
+	
694
+	total_frags=0;
695
+	memset(info,0, sizeof(*info));
696
+	info->total_size=qm->size;
697
+	info->min_frag=MIN_FRAG_SIZE;
698
+	info->free=qm->size-qm->real_used;
699
+	info->used=qm->used;
700
+	info->real_used=qm->real_used;
701
+	info->max_used=qm->max_real_used;
702
+	for(r=0;r<QM_HASH_SIZE; r++){
703
+		total_frags+=qm->free_hash[r].no;
704
+	}
705
+	info->total_frags=total_frags;
706
+}
707
+
687 708
 
688 709
 
689 710
 #endif
... ...
@@ -39,7 +39,7 @@
39 39
 #if !defined(q_malloc_h) && !defined(VQ_MALLOC) && !defined(F_MALLOC)
40 40
 #define q_malloc_h
41 41
 
42
-
42
+#include "meminfo.h"
43 43
 
44 44
 /* defs*/
45 45
 #ifdef DBG_QM_MALLOC
... ...
@@ -148,6 +148,7 @@ void* qm_realloc(struct qm_block*, void* p, unsigned long size);
148 148
 #endif
149 149
 
150 150
 void  qm_status(struct qm_block*);
151
+void  qm_info(struct qm_block*, struct meminfo*);
151 152
 
152 153
 
153 154
 #endif
... ...
@@ -31,6 +31,7 @@
31 31
  *  2003-06-29  added shm_realloc & replaced shm_resize (andrei)
32 32
  *  2003-11-19  reverted shm_resize to the old version, using
33 33
  *               realloc causes terrible fragmentation  (andrei)
34
+ * 2005-03-02   added shm_info() & re-eneabled locking on shm_status (andrei)
34 35
  */
35 36
 
36 37
 
... ...
@@ -74,6 +75,7 @@
74 74
 #	define MY_FREE fm_free
75 75
 #	define MY_REALLOC fm_realloc
76 76
 #	define MY_STATUS fm_status
77
+#	define MY_MEMINFO	fm_info
77 78
 #	define  shm_malloc_init fm_malloc_init
78 79
 #else
79 80
 #	include "q_malloc.h"
... ...
@@ -82,6 +84,7 @@
82 82
 #	define MY_FREE qm_free
83 83
 #	define MY_REALLOC qm_realloc
84 84
 #	define MY_STATUS qm_status
85
+#	define MY_MEMINFO	qm_info
85 86
 #	define  shm_malloc_init qm_malloc_init
86 87
 #endif
87 88
 
... ...
@@ -224,12 +227,18 @@ void* _shm_resize(void* ptr, unsigned int size);
224 224
 
225 225
 #define shm_status() \
226 226
 do { \
227
-		/*shm_lock();*/ \
227
+		shm_lock(); \
228 228
 		MY_STATUS(shm_block); \
229
-		/*shm_unlock();*/ \
229
+		shm_unlock(); \
230 230
 }while(0)
231 231
 
232 232
 
233
+#define shm_info(mi) \
234
+do{\
235
+	shm_lock(); \
236
+	MY_MEMINFO(shm_block, mi); \
237
+	shm_unlock(); \
238
+}while(0)
233 239
 
234 240
 
235 241
 #endif