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 91
 #include "globals.h"
91 92
 #include "fifo_server.h"
92 93
 #include "mem/mem.h"
94
+#include "mem/shm_mem.h" /* shm_info() */
93 95
 #include "sr_module.h"
94 96
 #include "pt.h"
95 97
 #include "db/db_fifo.h"
... ...
@@ -868,6 +870,35 @@ static int ps_fifo_cmd(FILE *stream, char *response_file )
868 870
 }
869 871
 
870 872
 
873
+
874
+static int meminfo_fifo_cmd( FILE *stream, char *response_file )
875
+{
876
+	struct meminfo mi;
877
+	
878
+	if (response_file==0 || *response_file==0 ) { 
879
+		LOG(L_ERR, "ERROR: meminfo_fifo_cmd: null file\n");
880
+		return -1;
881
+	}
882
+	
883
+#ifdef SHM_MEM
884
+	shm_info(&mi);
885
+	fifo_reply( response_file, "200 ok\n"
886
+					"total:%ld\n"
887
+					"free:%ld\n"
888
+					"used:%ld\n"
889
+					"max used:%ld\n"
890
+					"fragments:%ld\n",
891
+					mi.total_size, mi.free, mi.real_used,
892
+					mi.max_used, mi.total_frags);
893
+#else
894
+	fifo_reply( response_file, "400 No shared memory support\n");
895
+#endif
896
+
897
+	return 1;
898
+}
899
+
900
+
901
+
871 902
 int register_core_fifo()
872 903
 {
873 904
 	if (register_fifo_cmd(print_fifo_cmd, FIFO_PRINT, 0)<0) {
... ...
@@ -902,6 +933,10 @@ int register_core_fifo()
902 933
 		LOG(L_CRIT, "ERROR: unable to register '%s' FIFO cmd\n", FIFO_KILL);
903 934
 		return -1;
904 935
 	}
936
+	if (register_fifo_cmd(meminfo_fifo_cmd, FIFO_MEMINFO, 0)<0) {
937
+		LOG(L_CRIT, "ERROR: unable to register '%s' FIFO cmd\n", FIFO_MEMINFO);
938
+		return -1;
939
+	}
905 940
 	if (fifo_db_url==0) {
906 941
 		LOG(L_WARN,"WARNING: no fifo_db_url given - "
907 942
 			"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 162
 		n=FRAG_NEXT(frag);
162 163
 		n->size=rest-FRAG_OVERHEAD;
163 164
 		FRAG_CLEAR_USED(n); /* never used */
164
-#ifdef DBG_F_MALLOC
165
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
165 166
 		qm->real_used+=FRAG_OVERHEAD;
167
+#endif
168
+#ifdef DBG_F_MALLOC
166 169
 		/* frag created by malloc, mark it*/
167 170
 		n->file=file;
168 171
 		n->func="frag. from fm_malloc";
... ...
@@ -206,7 +209,7 @@ struct fm_block* fm_malloc_init(char* address, unsigned long size)
206 209
 	memset(qm, 0, sizeof(struct fm_block));
207 210
 	size-=init_overhead;
208 211
 	qm->size=size;
209
-#ifdef DBG_F_MALLOC
212
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
210 213
 	qm->real_used=init_overhead;
211 214
 	qm->max_real_used=qm->real_used;
212 215
 #endif
... ...
@@ -275,11 +278,6 @@ found:
275 278
 	
276 279
 #ifdef DBG_F_MALLOC
277 280
 	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 281
 
284 282
 	frag->file=file;
285 283
 	frag->func=func;
... ...
@@ -289,6 +287,12 @@ found:
289 287
 		(char*)frag+sizeof(struct fm_frag));
290 288
 #else
291 289
 	fm_split_frag(qm, frag, size);
290
+#endif
291
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
292
+	qm->real_used+=frag->size;
293
+	qm->used+=frag->size;
294
+	if (qm->max_real_used<qm->real_used)
295
+		qm->max_real_used=qm->real_used;
292 296
 #endif
293 297
 	FRAG_MARK_USED(frag); /* mark it as used */
294 298
 	return (char*)frag+sizeof(struct fm_frag);
... ...
@@ -324,10 +328,11 @@ void fm_free(struct fm_block* qm, void* p)
324 328
 			f->line);
325 329
 #endif
326 330
 	size=f->size;
327
-
328
-#ifdef DBG_F_MALLOC
331
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
329 332
 	qm->used-=size;
330 333
 	qm->real_used-=size;
334
+#endif
335
+#ifdef DBG_F_MALLOC
331 336
 	f->file=file;
332 337
 	f->func=func;
333 338
 	f->line=line;
... ...
@@ -387,10 +392,12 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size)
387 392
 #ifdef DBG_F_MALLOC
388 393
 		DBG("fm_realloc: shrinking from %lu to %lu\n", f->size, size);
389 394
 		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 395
 #else
393 396
 		fm_split_frag(qm, f, size);
397
+#endif
398
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
399
+		qm->real_used-=(orig_size-f->size);
400
+		qm->used-=(orig_size-f->size);
394 401
 #endif
395 402
 	}else if (f->size<size){
396 403
 		/* grow */
... ...
@@ -418,7 +425,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size)
418 425
 			qm->free_hash[hash].no--;
419 426
 			/* join */
420 427
 			f->size+=n->size+FRAG_OVERHEAD;
421
-		#ifdef DBG_F_MALLOC
428
+		#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
422 429
 			qm->real_used-=FRAG_OVERHEAD;
423 430
 		#endif
424 431
 			/* split it if necessary */
... ...
@@ -430,7 +437,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size)
430 437
 				fm_split_frag(qm, f, size);
431 438
 		#endif
432 439
 			}
433
-		#ifdef DBG_F_MALLOC
440
+		#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
434 441
 			qm->real_used+=(f->size-orig_size);
435 442
 			qm->used+=(f->size-orig_size);
436 443
 		#endif
... ...
@@ -478,7 +485,7 @@ void fm_status(struct fm_block* qm)
478 485
 	if (!qm) return;
479 486
 
480 487
 	LOG(memlog, " heap size= %ld\n", qm->size);
481
-#ifdef DBG_F_MALLOC
488
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
482 489
 	LOG(memlog, " used= %lu, used+overhead=%lu, free=%lu\n",
483 490
 			qm->used, qm->real_used, qm->size-qm->real_used);
484 491
 	LOG(memlog, " max used (+overhead)= %lu\n", qm->max_real_used);
... ...
@@ -540,5 +547,46 @@ void fm_status(struct fm_block* qm)
540 547
 
541 548
 
542 549
 
550
+/* fills a malloc info structure with info about the block
551
+ * if a parameter is not supported, it will be filled with 0 */
552
+void fm_info(struct fm_block* qm, struct meminfo* info)
553
+{
554
+	int r;
555
+	long total_frags;
556
+#if !defined(DBG_F_MALLOC) && !defined(MALLOC_STATS)
557
+	struct fm_frag* f;
558
+#endif
559
+	
560
+	memset(info,0, sizeof(*info));
561
+	total_frags=0;
562
+	info->total_size=qm->size;
563
+	info->min_frag=MIN_FRAG_SIZE;
564
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
565
+	info->free=qm->size-qm->real_used;
566
+	info->used=qm->used;
567
+	info->real_used=qm->real_used;
568
+	info->max_used=qm->max_real_used;
569
+	for(r=0;r<F_HASH_SIZE; r++){
570
+		total_frags+=qm->free_hash[r].no;
571
+	}
572
+#else
573
+	/* we'll have to compute it all */
574
+	for (r=0; r<=F_MALLOC_OPTIMIZE/ROUNDTO; r++){
575
+		info->free+=qm->free_hash[r].no*UN_HASH(r);
576
+		total_frags+=qm->free_hash[r].no;
577
+	}
578
+	for(;r<F_HASH_SIZE; r++){
579
+		total_frags+=qm->free_hash[r].no;
580
+		for(f=qm->free_hash[r].first;f;f=f->u.nxt_free){
581
+			info->free+=f->size;
582
+		}
583
+	}
584
+	info->real_used=info->total_size-info->free;
585
+	info->used=0; /* we don't really now */
586
+	info->max_used=0; /* we don't really now */
587
+#endif
588
+	info->total_frags=total_frags;
589
+}
590
+
543 591
 
544 592
 #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 99
 
96 100
 struct fm_block{
97 101
 	unsigned long size; /* total size */
98
-#ifdef DBG_F_MALLOC
102
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
99 103
 	unsigned long used; /* alloc'ed size*/
100 104
 	unsigned long real_used; /* used+malloc overhead*/
101 105
 	unsigned long max_real_used;
... ...
@@ -133,6 +137,7 @@ void*  fm_realloc(struct fm_block*, void* p, unsigned long size);
133 137
 #endif
134 138
 
135 139
 void  fm_status(struct fm_block*);
140
+void  fm_info(struct fm_block*, struct meminfo*);
136 141
 
137 142
 
138 143
 #endif
139 144
new file mode 100644
... ...
@@ -0,0 +1,48 @@
1
+/* $Id$*
2
+ *
3
+ * mem (malloc) info 
4
+ *
5
+ * Copyright (C) 2001-2003 FhG Fokus
6
+ *
7
+ * This file is part of ser, a free SIP server.
8
+ *
9
+ * ser is free software; you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation; either version 2 of the License, or
12
+ * (at your option) any later version
13
+ *
14
+ * For a license to use the ser software under conditions
15
+ * other than those described here, or to purchase support for this
16
+ * software, please contact iptel.org by e-mail at the following addresses:
17
+ *    info@iptel.org
18
+ *
19
+ * ser is distributed in the hope that it will be useful,
20
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
+ * GNU General Public License for more details.
23
+ *
24
+ * You should have received a copy of the GNU General Public License 
25
+ * along with this program; if not, write to the Free Software 
26
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
+ */
28
+/*
29
+ * History:
30
+ * --------
31
+ *  2005-03-02  created (andrei)
32
+ */
33
+
34
+#ifndef meminfo_h
35
+#define meminfo_h
36
+
37
+struct meminfo{
38
+	unsigned long total_size;
39
+	unsigned long free;
40
+	unsigned long used;
41
+	unsigned long real_used; /*used + overhead*/
42
+	unsigned long max_used;
43
+	unsigned long min_frag;
44
+	unsigned long total_frags; /* total fragment no */
45
+};
46
+
47
+#endif
48
+
... ...
@@ -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 685
 }
685 686
 
686 687
 
688
+/* fills a malloc info structure with info about the block
689
+ * if a parameter is not supported, it will be filled with 0 */
690
+void qm_info(struct qm_block* qm, struct meminfo* info)
691
+{
692
+	int r;
693
+	long total_frags;
694
+	
695
+	total_frags=0;
696
+	memset(info,0, sizeof(*info));
697
+	info->total_size=qm->size;
698
+	info->min_frag=MIN_FRAG_SIZE;
699
+	info->free=qm->size-qm->real_used;
700
+	info->used=qm->used;
701
+	info->real_used=qm->real_used;
702
+	info->max_used=qm->max_real_used;
703
+	for(r=0;r<QM_HASH_SIZE; r++){
704
+		total_frags+=qm->free_hash[r].no;
705
+	}
706
+	info->total_frags=total_frags;
707
+}
708
+
687 709
 
688 710
 
689 711
 #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 75
 #	define MY_FREE fm_free
75 76
 #	define MY_REALLOC fm_realloc
76 77
 #	define MY_STATUS fm_status
78
+#	define MY_MEMINFO	fm_info
77 79
 #	define  shm_malloc_init fm_malloc_init
78 80
 #else
79 81
 #	include "q_malloc.h"
... ...
@@ -82,6 +84,7 @@
82 84
 #	define MY_FREE qm_free
83 85
 #	define MY_REALLOC qm_realloc
84 86
 #	define MY_STATUS qm_status
87
+#	define MY_MEMINFO	qm_info
85 88
 #	define  shm_malloc_init qm_malloc_init
86 89
 #endif
87 90
 
... ...
@@ -224,12 +227,18 @@ void* _shm_resize(void* ptr, unsigned int size);
224 227
 
225 228
 #define shm_status() \
226 229
 do { \
227
-		/*shm_lock();*/ \
230
+		shm_lock(); \
228 231
 		MY_STATUS(shm_block); \
229
-		/*shm_unlock();*/ \
232
+		shm_unlock(); \
230 233
 }while(0)
231 234
 
232 235
 
236
+#define shm_info(mi) \
237
+do{\
238
+	shm_lock(); \
239
+	MY_MEMINFO(shm_block, mi); \
240
+	shm_unlock(); \
241
+}while(0)
233 242
 
234 243
 
235 244
 #endif