Browse Source

- 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 20 years ago
parent
commit
51dffb0afd
9 changed files with 188 additions and 19 deletions
  1. 1 1
      Makefile.defs
  2. 35 0
      fifo_server.c
  3. 1 0
      fifo_server.h
  4. 62 14
      mem/f_malloc.c
  5. 6 1
      mem/f_malloc.h
  6. 48 0
      mem/meminfo.h
  7. 22 0
      mem/q_malloc.c
  8. 2 1
      mem/q_malloc.h
  9. 11 2
      mem/shm_mem.h

+ 1 - 1
Makefile.defs

@@ -53,7 +53,7 @@ MAIN_NAME=ser
 VERSION = 0
 PATCHLEVEL = 10
 SUBLEVEL =   99
-EXTRAVERSION = -dev2
+EXTRAVERSION = -dev3
 
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")

+ 35 - 0
fifo_server.c

@@ -64,6 +64,7 @@
  *  2004-04-29  added chown(sock_user, sock_group)  (andrei)
  *  2004-06-06  updated to the new DB interface  & init_db_fifo (andrei)
  *  2004-09-19  fifo is deleted on exit (destroy_fifo)  (andrei)
+ *  2005-03-02  meminfo fifo cmd added (andrei)
  */
 
 
@@ -90,6 +91,7 @@
 #include "globals.h"
 #include "fifo_server.h"
 #include "mem/mem.h"
+#include "mem/shm_mem.h" /* shm_info() */
 #include "sr_module.h"
 #include "pt.h"
 #include "db/db_fifo.h"
@@ -868,6 +870,35 @@ static int ps_fifo_cmd(FILE *stream, char *response_file )
 }
 
 
+
+static int meminfo_fifo_cmd( FILE *stream, char *response_file )
+{
+	struct meminfo mi;
+	
+	if (response_file==0 || *response_file==0 ) { 
+		LOG(L_ERR, "ERROR: meminfo_fifo_cmd: null file\n");
+		return -1;
+	}
+	
+#ifdef SHM_MEM
+	shm_info(&mi);
+	fifo_reply( response_file, "200 ok\n"
+					"total:%ld\n"
+					"free:%ld\n"
+					"used:%ld\n"
+					"max used:%ld\n"
+					"fragments:%ld\n",
+					mi.total_size, mi.free, mi.real_used,
+					mi.max_used, mi.total_frags);
+#else
+	fifo_reply( response_file, "400 No shared memory support\n");
+#endif
+
+	return 1;
+}
+
+
+
 int register_core_fifo()
 {
 	if (register_fifo_cmd(print_fifo_cmd, FIFO_PRINT, 0)<0) {
@@ -902,6 +933,10 @@ int register_core_fifo()
 		LOG(L_CRIT, "ERROR: unable to register '%s' FIFO cmd\n", FIFO_KILL);
 		return -1;
 	}
+	if (register_fifo_cmd(meminfo_fifo_cmd, FIFO_MEMINFO, 0)<0) {
+		LOG(L_CRIT, "ERROR: unable to register '%s' FIFO cmd\n", FIFO_MEMINFO);
+		return -1;
+	}
 	if (fifo_db_url==0) {
 		LOG(L_WARN,"WARNING: no fifo_db_url given - "
 			"fifo DB commands disabled!\n");

+ 1 - 0
fifo_server.h

@@ -51,6 +51,7 @@
 #define FIFO_PWD "pwd"
 /* kill the server */
 #define FIFO_KILL "kill"
+#define FIFO_MEMINFO "meminfo"
 
 #define MAX_CTIME_LEN 128
 

+ 62 - 14
mem/f_malloc.c

@@ -33,6 +33,7 @@
  *               memory blocks (64 bits machine & size >=2^32) 
  *              GET_HASH s/</<=/ (avoids waste of 1 hash cell)   (andrei)
  *  2004-11-10  support for > 4Gb mem., switched to long (andrei)
+ *  2005-03-02  added fm_info() (andrei)
  */
 
 
@@ -161,8 +162,10 @@ void fm_split_frag(struct fm_block* qm, struct fm_frag* frag,
 		n=FRAG_NEXT(frag);
 		n->size=rest-FRAG_OVERHEAD;
 		FRAG_CLEAR_USED(n); /* never used */
-#ifdef DBG_F_MALLOC
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
 		qm->real_used+=FRAG_OVERHEAD;
+#endif
+#ifdef DBG_F_MALLOC
 		/* frag created by malloc, mark it*/
 		n->file=file;
 		n->func="frag. from fm_malloc";
@@ -206,7 +209,7 @@ struct fm_block* fm_malloc_init(char* address, unsigned long size)
 	memset(qm, 0, sizeof(struct fm_block));
 	size-=init_overhead;
 	qm->size=size;
-#ifdef DBG_F_MALLOC
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
 	qm->real_used=init_overhead;
 	qm->max_real_used=qm->real_used;
 #endif
@@ -275,11 +278,6 @@ found:
 	
 #ifdef DBG_F_MALLOC
 	fm_split_frag(qm, frag, size, file, func, line);
-	qm->real_used+=frag->size;
-	qm->used+=frag->size;
-
-	if (qm->max_real_used<qm->real_used)
-		qm->max_real_used=qm->real_used;
 
 	frag->file=file;
 	frag->func=func;
@@ -289,6 +287,12 @@ found:
 		(char*)frag+sizeof(struct fm_frag));
 #else
 	fm_split_frag(qm, frag, size);
+#endif
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
+	qm->real_used+=frag->size;
+	qm->used+=frag->size;
+	if (qm->max_real_used<qm->real_used)
+		qm->max_real_used=qm->real_used;
 #endif
 	FRAG_MARK_USED(frag); /* mark it as used */
 	return (char*)frag+sizeof(struct fm_frag);
@@ -324,10 +328,11 @@ void fm_free(struct fm_block* qm, void* p)
 			f->line);
 #endif
 	size=f->size;
-
-#ifdef DBG_F_MALLOC
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
 	qm->used-=size;
 	qm->real_used-=size;
+#endif
+#ifdef DBG_F_MALLOC
 	f->file=file;
 	f->func=func;
 	f->line=line;
@@ -387,10 +392,12 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size)
 #ifdef DBG_F_MALLOC
 		DBG("fm_realloc: shrinking from %lu to %lu\n", f->size, size);
 		fm_split_frag(qm, f, size, file, "frag. from fm_realloc", line);
-		qm->real_used-=(orig_size-f->size);
-		qm->used-=(orig_size-f->size);
 #else
 		fm_split_frag(qm, f, size);
+#endif
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
+		qm->real_used-=(orig_size-f->size);
+		qm->used-=(orig_size-f->size);
 #endif
 	}else if (f->size<size){
 		/* grow */
@@ -418,7 +425,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size)
 			qm->free_hash[hash].no--;
 			/* join */
 			f->size+=n->size+FRAG_OVERHEAD;
-		#ifdef DBG_F_MALLOC
+		#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
 			qm->real_used-=FRAG_OVERHEAD;
 		#endif
 			/* split it if necessary */
@@ -430,7 +437,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size)
 				fm_split_frag(qm, f, size);
 		#endif
 			}
-		#ifdef DBG_F_MALLOC
+		#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
 			qm->real_used+=(f->size-orig_size);
 			qm->used+=(f->size-orig_size);
 		#endif
@@ -478,7 +485,7 @@ void fm_status(struct fm_block* qm)
 	if (!qm) return;
 
 	LOG(memlog, " heap size= %ld\n", qm->size);
-#ifdef DBG_F_MALLOC
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
 	LOG(memlog, " used= %lu, used+overhead=%lu, free=%lu\n",
 			qm->used, qm->real_used, qm->size-qm->real_used);
 	LOG(memlog, " max used (+overhead)= %lu\n", qm->max_real_used);
@@ -540,5 +547,46 @@ void fm_status(struct fm_block* qm)
 
 
 
+/* fills a malloc info structure with info about the block
+ * if a parameter is not supported, it will be filled with 0 */
+void fm_info(struct fm_block* qm, struct meminfo* info)
+{
+	int r;
+	long total_frags;
+#if !defined(DBG_F_MALLOC) && !defined(MALLOC_STATS)
+	struct fm_frag* f;
+#endif
+	
+	memset(info,0, sizeof(*info));
+	total_frags=0;
+	info->total_size=qm->size;
+	info->min_frag=MIN_FRAG_SIZE;
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
+	info->free=qm->size-qm->real_used;
+	info->used=qm->used;
+	info->real_used=qm->real_used;
+	info->max_used=qm->max_real_used;
+	for(r=0;r<F_HASH_SIZE; r++){
+		total_frags+=qm->free_hash[r].no;
+	}
+#else
+	/* we'll have to compute it all */
+	for (r=0; r<=F_MALLOC_OPTIMIZE/ROUNDTO; r++){
+		info->free+=qm->free_hash[r].no*UN_HASH(r);
+		total_frags+=qm->free_hash[r].no;
+	}
+	for(;r<F_HASH_SIZE; r++){
+		total_frags+=qm->free_hash[r].no;
+		for(f=qm->free_hash[r].first;f;f=f->u.nxt_free){
+			info->free+=f->size;
+		}
+	}
+	info->real_used=info->total_size-info->free;
+	info->used=0; /* we don't really now */
+	info->max_used=0; /* we don't really now */
+#endif
+	info->total_frags=total_frags;
+}
+
 
 #endif

+ 6 - 1
mem/f_malloc.h

@@ -39,7 +39,11 @@
 #if !defined(f_malloc_h) && !defined(VQ_MALLOC) 
 #define f_malloc_h
 
+#ifdef DBG_QM_MALLOC
+#define DBG_F_MALLOC
+#endif
 
+#include "meminfo.h"
 
 /* defs*/
 
@@ -95,7 +99,7 @@ struct fm_frag_lnk{
 
 struct fm_block{
 	unsigned long size; /* total size */
-#ifdef DBG_F_MALLOC
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
 	unsigned long used; /* alloc'ed size*/
 	unsigned long real_used; /* used+malloc overhead*/
 	unsigned long max_real_used;
@@ -133,6 +137,7 @@ void*  fm_realloc(struct fm_block*, void* p, unsigned long size);
 #endif
 
 void  fm_status(struct fm_block*);
+void  fm_info(struct fm_block*, struct meminfo*);
 
 
 #endif

+ 48 - 0
mem/meminfo.h

@@ -0,0 +1,48 @@
+/* $Id$*
+ *
+ * mem (malloc) info 
+ *
+ * Copyright (C) 2001-2003 FhG Fokus
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+/*
+ * History:
+ * --------
+ *  2005-03-02  created (andrei)
+ */
+
+#ifndef meminfo_h
+#define meminfo_h
+
+struct meminfo{
+	unsigned long total_size;
+	unsigned long free;
+	unsigned long used;
+	unsigned long real_used; /*used + overhead*/
+	unsigned long max_used;
+	unsigned long min_frag;
+	unsigned long total_frags; /* total fragment no */
+};
+
+#endif
+

+ 22 - 0
mem/q_malloc.c

@@ -34,6 +34,7 @@
  *               memory blocks (64 bits machine & size>=2^32) (andrei)
  *              GET_HASH s/</<=/ (avoids waste of 1 hash cell) (andrei)
  *  2004-11-10  support for > 4Gb mem., switched to long (andrei)
+ *  2005-03-02  added qm_info() (andrei)
  */
 
 
@@ -684,6 +685,27 @@ void qm_status(struct qm_block* qm)
 }
 
 
+/* fills a malloc info structure with info about the block
+ * if a parameter is not supported, it will be filled with 0 */
+void qm_info(struct qm_block* qm, struct meminfo* info)
+{
+	int r;
+	long total_frags;
+	
+	total_frags=0;
+	memset(info,0, sizeof(*info));
+	info->total_size=qm->size;
+	info->min_frag=MIN_FRAG_SIZE;
+	info->free=qm->size-qm->real_used;
+	info->used=qm->used;
+	info->real_used=qm->real_used;
+	info->max_used=qm->max_real_used;
+	for(r=0;r<QM_HASH_SIZE; r++){
+		total_frags+=qm->free_hash[r].no;
+	}
+	info->total_frags=total_frags;
+}
+
 
 
 #endif

+ 2 - 1
mem/q_malloc.h

@@ -39,7 +39,7 @@
 #if !defined(q_malloc_h) && !defined(VQ_MALLOC) && !defined(F_MALLOC)
 #define q_malloc_h
 
-
+#include "meminfo.h"
 
 /* defs*/
 #ifdef DBG_QM_MALLOC
@@ -148,6 +148,7 @@ void* qm_realloc(struct qm_block*, void* p, unsigned long size);
 #endif
 
 void  qm_status(struct qm_block*);
+void  qm_info(struct qm_block*, struct meminfo*);
 
 
 #endif

+ 11 - 2
mem/shm_mem.h

@@ -31,6 +31,7 @@
  *  2003-06-29  added shm_realloc & replaced shm_resize (andrei)
  *  2003-11-19  reverted shm_resize to the old version, using
  *               realloc causes terrible fragmentation  (andrei)
+ * 2005-03-02   added shm_info() & re-eneabled locking on shm_status (andrei)
  */
 
 
@@ -74,6 +75,7 @@
 #	define MY_FREE fm_free
 #	define MY_REALLOC fm_realloc
 #	define MY_STATUS fm_status
+#	define MY_MEMINFO	fm_info
 #	define  shm_malloc_init fm_malloc_init
 #else
 #	include "q_malloc.h"
@@ -82,6 +84,7 @@
 #	define MY_FREE qm_free
 #	define MY_REALLOC qm_realloc
 #	define MY_STATUS qm_status
+#	define MY_MEMINFO	qm_info
 #	define  shm_malloc_init qm_malloc_init
 #endif
 
@@ -224,12 +227,18 @@ void* _shm_resize(void* ptr, unsigned int size);
 
 #define shm_status() \
 do { \
-		/*shm_lock();*/ \
+		shm_lock(); \
 		MY_STATUS(shm_block); \
-		/*shm_unlock();*/ \
+		shm_unlock(); \
 }while(0)
 
 
+#define shm_info(mi) \
+do{\
+	shm_lock(); \
+	MY_MEMINFO(shm_block, mi); \
+	shm_unlock(); \
+}while(0)
 
 
 #endif