Browse code

mem: summarize in-use memory on exit

Additional qm_sums and fm_sums as extension to qm_status/fm_status, with
summarized values per allocation source.
Slightly modified SER-224 patch version (no locking, sr changes --andrei).

Closes SER-224.

Signed-off-by: Andrei Pelinescu-Onciul <andrei@iptel.org>

Dragos Vingarzan authored on 28/09/2009 20:01:17 • Andrei Pelinescu-Onciul committed on 29/09/2009 17:03:40
Showing 7 changed files
... ...
@@ -532,6 +532,8 @@ void cleanup(show_status)
532 532
 	if (show_status){
533 533
 		LOG(memlog, "Memory status (pkg):\n");
534 534
 		pkg_status();
535
+		LOG(memlog, "Memory still-in-use summary (pkg):\n");
536
+		pkg_sums();
535 537
 	}
536 538
 #endif
537 539
 #ifdef SHM_MEM
... ...
@@ -540,6 +542,8 @@ void cleanup(show_status)
540 542
 	if (show_status){
541 543
 			LOG(memlog, "Memory status (shm):\n");
542 544
 			shm_status();
545
+			LOG(memlog, "Memory still-in-use summary (shm):\n");
546
+			shm_sums();
543 547
 	}
544 548
 	/* zero all shmem alloc vars that we still use */
545 549
 	shm_mem_destroy();
... ...
@@ -40,6 +40,7 @@
40 40
  *  2006-04-07  s/DBG/MDBG (andrei)
41 41
  *  2007-02-23  added fm_available() (andrei)
42 42
  *  2007-06-23  added hash bitmap (andrei)
43
+ *  2009-09-28  added fm_sums() (patch from Dragos Vingarzan)
43 44
  */
44 45
 
45 46
 
... ...
@@ -711,4 +712,85 @@ unsigned long fm_available(struct fm_block* qm)
711 712
 #endif
712 713
 }
713 714
 
715
+
716
+#ifdef DBG_F_MALLOC
717
+
718
+typedef struct _mem_counter{
719
+	const char *file;
720
+	const char *func;
721
+	unsigned long line;
722
+	
723
+	unsigned long size;
724
+	int count;
725
+	
726
+	struct _mem_counter *next;
727
+} mem_counter;
728
+
729
+static mem_counter* get_mem_counter(mem_counter **root,struct fm_frag* f)
730
+{
731
+	mem_counter *x;
732
+	
733
+	if (!*root) goto make_new;
734
+	for(x=*root;x;x=x->next)
735
+		if (x->file == f->file && x->func == f->func && x->line == f->line)
736
+			return x;
737
+make_new:	
738
+	x = malloc(sizeof(mem_counter));
739
+	x->file = f->file;
740
+	x->func = f->func;
741
+	x->line = f->line;
742
+	x->count = 0;
743
+	x->size = 0;
744
+	x->next = *root;
745
+	*root = x;
746
+	return x;
747
+}
748
+
749
+
750
+
751
+void fm_sums(struct fm_block* qm)
752
+{
753
+	struct fm_frag* f;
754
+	struct fm_frag* free_frag;
755
+	int i, hash;
756
+	mem_counter *root,*x;
757
+	
758
+	root=0;
759
+	if (!qm) return;
760
+
761
+	LOG(memlog, "summarizing all alloc'ed. fragments:\n");
762
+	
763
+	for (f=qm->first_frag, i=0; (char*)f<(char*)qm->last_frag;
764
+			f=FRAG_NEXT(f), i++){
765
+		if (f->u.nxt_free==0){
766
+			/* it might be in-use or the last free fragm. in a free list 
767
+			   => search the free frags of the same size for a possible
768
+			   match --andrei*/
769
+			hash=GET_HASH(f->size);
770
+			for(free_frag=qm->free_hash[hash].first;
771
+					free_frag && (free_frag!=f);
772
+					free_frag=free_frag->u.nxt_free);
773
+			if (free_frag==0){ /* not found among the free frag */
774
+				x = get_mem_counter(&root,f);
775
+				x->count++;
776
+				x->size+=f->size;
777
+			}
778
+		}
779
+	}
780
+	x = root;
781
+	while(x){
782
+		LOG(memlog, " count=%6d size=%10lu bytes from %s: %s(%ld)\n",
783
+			x->count,x->size,
784
+			x->file, x->func, x->line
785
+			);
786
+		root = x->next;
787
+		free(x);
788
+		x = root;
789
+	}
790
+	LOG(memlog, "-----------------------------\n");
791
+}
792
+#endif /* DBG_F_MALLOC */
793
+
794
+
795
+
714 796
 #endif
... ...
@@ -155,4 +155,10 @@ void  fm_info(struct fm_block*, struct mem_info*);
155 155
 
156 156
 unsigned long fm_available(struct fm_block*);
157 157
 
158
+#ifdef DBG_F_MALLOC
159
+void fm_sums(struct fm_block*);
160
+#else
161
+#define fm_sums(v) do{}while(0)
162
+#endif /* DBG_F_MALLOC */
163
+
158 164
 #endif
... ...
@@ -120,20 +120,24 @@
120 120
 #		define pkg_status()    fm_status(mem_block)
121 121
 #		define pkg_info(mi)    fm_info(mem_block, mi)
122 122
 #		define pkg_available() fm_available(mem_block)
123
+#		define pkg_sums()      fm_sums(mem_block)
123 124
 #	elif defined DL_MALLOC
124 125
 #		define pkg_status()  0
125 126
 #		define pkg_info(mi)  0
126 127
 #		define pkg_available()  0
128
+#		define pkg_sums()  0
127 129
 #	else
128 130
 #		define pkg_status()    qm_status(mem_block)
129 131
 #		define pkg_info(mi)    qm_info(mem_block, mi)
130 132
 #		define pkg_available() qm_available(mem_block)
133
+#		define pkg_sums()      qm_sums(mem_block)
131 134
 #	endif
132 135
 #elif defined(SHM_MEM) && defined(USE_SHM_MEM)
133 136
 #	include "shm_mem.h"
134 137
 #	define pkg_malloc(s) shm_malloc((s))
135 138
 #	define pkg_free(p)   shm_free((p))
136 139
 #	define pkg_status()  shm_status()
140
+#	define pkg_sums()    shm_sums()
137 141
 #else
138 142
 #	include <stdlib.h>
139 143
 #	include "memdbg.h"
... ...
@@ -147,6 +151,7 @@
147 151
 	    ____v123; } )
148 152
 #	define pkg_free(p)  do{ MDBG("free %p\n", (p)); free((p)); }while(0);
149 153
 #	define pkg_status()
154
+#	define pkg_sums()
150 155
 #endif
151 156
 
152 157
 int init_pkg_mallocs();
... ...
@@ -40,6 +40,7 @@
40 40
  *  2006-02-03  fixed realloc out of mem. free bug (andrei)
41 41
  *  2006-04-07  s/DBG/MDBG (andrei)
42 42
  *  2007-02-23  added fm_available() (andrei)
43
+ *  2009-09-28  added fm_sums() (patch from Dragos Vingarzan)
43 44
  */
44 45
 
45 46
 
... ...
@@ -779,4 +780,73 @@ unsigned long qm_available(struct qm_block* qm)
779 780
 }
780 781
 
781 782
 
783
+
784
+#ifdef DBG_QM_MALLOC
785
+
786
+typedef struct _mem_counter{
787
+	const char *file;
788
+	const char *func;
789
+	unsigned long line;
790
+	
791
+	unsigned long size;
792
+	int count;
793
+	
794
+	struct _mem_counter *next;
795
+} mem_counter;
796
+
797
+static mem_counter* get_mem_counter(mem_counter **root, struct qm_frag* f)
798
+{
799
+	mem_counter *x;
800
+	if (!*root) goto make_new;
801
+	for(x=*root;x;x=x->next)
802
+		if (x->file == f->file && x->func == f->func && x->line == f->line)
803
+			return x;
804
+make_new:	
805
+	x = malloc(sizeof(mem_counter));
806
+	x->file = f->file;
807
+	x->func = f->func;
808
+	x->line = f->line;
809
+	x->count = 0;
810
+	x->size = 0;
811
+	x->next = *root;
812
+	*root = x;
813
+	return x;
814
+}
815
+
816
+
817
+
818
+void qm_sums(struct qm_block* qm)
819
+{
820
+	struct qm_frag* f;
821
+	int i;
822
+	mem_counter *root, *x;
823
+	
824
+	root=0;
825
+	if (!qm) return;
826
+	
827
+	LOG(memlog, "summarizing all alloc'ed. fragments:\n");
828
+	
829
+	for (f=qm->first_frag, i=0;(char*)f<(char*)qm->last_frag_end;
830
+			f=FRAG_NEXT(f),i++){
831
+		if (! f->u.is_free){
832
+			x = get_mem_counter(&root,f);
833
+			x->count++;
834
+			x->size+=f->size;
835
+		}
836
+	}
837
+	x = root;
838
+	while(x){
839
+		LOG(memlog, " count=%6d size=%10lu bytes from %s: %s(%ld)\n",
840
+			x->count,x->size,
841
+			x->file, x->func, x->line
842
+			);
843
+		root = x->next;
844
+		free(x);
845
+		x = root;
846
+	}
847
+	LOG(memlog, "-----------------------------\n");
848
+}
849
+#endif /* DBG_QM_MALLOC */
850
+
851
+
782 852
 #endif
... ...
@@ -153,4 +153,10 @@ void  qm_info(struct qm_block*, struct mem_info*);
153 153
 
154 154
 unsigned long qm_available(struct qm_block* qm);
155 155
 
156
+#ifdef DBG_QM_MALLOC
157
+void qm_sums(struct qm_block* qm);
158
+#else
159
+#define qm_sums(v) do{}while(0)
160
+#endif /*DBQ_QM_MALLOC */
161
+
156 162
 #endif
... ...
@@ -98,6 +98,7 @@
98 98
 #	define shm_free_unsafe shm_free
99 99
 #	define shm_available	sfm_available(shm_block)
100 100
 #	define shm_status() sfm_status(shm_block)
101
+#	define shm_sums() do{}while(0)
101 102
 #	define shm_malloc_init sfm_malloc_init
102 103
 #	define shm_malloc_destroy(b) sfm_malloc_destroy(b)
103 104
 #	define shm_malloc_on_fork()	sfm_pool_reset()
... ...
@@ -124,6 +125,7 @@
124 125
 #	define shm_free_unsafe shm_free
125 126
 #	define shm_available	sfm_available(shm_block)
126 127
 #	define shm_status() sfm_status(shm_block)
128
+#	define shm_sums() do{}while(0)
127 129
 #	define shm_malloc_init sfm_malloc_init
128 130
 #	define shm_malloc_destroy(b) sfm_malloc_destroy(b)
129 131
 #	define shm_malloc_on_fork()	sfm_pool_reset()
... ...
@@ -133,6 +135,7 @@
133 135
 #	define MY_MALLOC vqm_malloc
134 136
 #	define MY_FREE vqm_free
135 137
 #	define MY_STATUS vqm_status
138
+#	define MY_SUMS do{}while(0)
136 139
 #	define  shm_malloc_init vqm_malloc_init
137 140
 #	define shm_malloc_destroy(b) do{}while(0)
138 141
 #	define shm_malloc_on_fork() do{}while(0)
... ...
@@ -145,6 +148,7 @@
145 148
 #	define MY_REALLOC fm_realloc
146 149
 #	define MY_STATUS fm_status
147 150
 #	define MY_MEMINFO	fm_info
151
+#	define MY_SUMS	fm_sums
148 152
 #	define  shm_malloc_init fm_malloc_init
149 153
 #	define shm_malloc_destroy(b) do{}while(0)
150 154
 #	define shm_available() fm_available(shm_block)
... ...
@@ -156,6 +160,7 @@
156 160
 #	define MY_FREE mspace_free
157 161
 #	define MY_REALLOC mspace_realloc
158 162
 #	define MY_STATUS(...) 0
163
+#	define MY_SUMS do{}while(0)
159 164
 #	define MY_MEMINFO	mspace_info
160 165
 #	define  shm_malloc_init(buf, len) create_mspace_with_base(buf, len, 0)
161 166
 #	define shm_malloc_destroy(b) do{}while(0)
... ...
@@ -168,6 +173,7 @@
168 173
 #	define MY_REALLOC qm_realloc
169 174
 #	define MY_STATUS qm_status
170 175
 #	define MY_MEMINFO	qm_info
176
+#	define MY_SUMS	qm_sums
171 177
 #	define  shm_malloc_init qm_malloc_init
172 178
 #	define shm_malloc_destroy(b) do{}while(0)
173 179
 #	define shm_available() qm_available(shm_block)
... ...
@@ -318,6 +324,16 @@ do{\
318 324
 	shm_unlock(); \
319 325
 }while(0)
320 326
 
327
+#ifdef MY_SUMS
328
+#define shm_sums() \
329
+	do { \
330
+		shm_lock(); \
331
+		MY_SUMS(shm_block); \
332
+		shm_unlock(); \
333
+	}while(0)
334
+	
335
+#endif /* MY_SUMS */
336
+
321 337
 #endif /* ! SHM_SAFE_MALLOC */
322 338
 
323 339
 #endif /* shm_mem_h */