mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +00:00 
			
		
		
		
	astmm.c: Add more stats to CLI "memory show" commands.
* Add freed regions totals to allocations and summary. * Add totals for all allocations and not just the selected allocations. Change-Id: I61d5a5112617b0733097f2545a3006a344b4032a
This commit is contained in:
		
							
								
								
									
										107
									
								
								main/astmm.c
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								main/astmm.c
									
									
									
									
									
								
							| @@ -663,6 +663,32 @@ int __ast_vasprintf(char **strp, const char *fmt, va_list ap, const char *file, | ||||
| 	return size; | ||||
| } | ||||
|  | ||||
| /*! | ||||
|  * \internal | ||||
|  * \brief Count the number of bytes in the specified freed region. | ||||
|  * | ||||
|  * \param freed Already freed region blocks storage. | ||||
|  * | ||||
|  * \note reglock must be locked before calling. | ||||
|  * | ||||
|  * \return Number of bytes in freed region. | ||||
|  */ | ||||
| static size_t freed_regions_size(struct ast_freed_regions *freed) | ||||
| { | ||||
| 	size_t total_len = 0; | ||||
| 	int idx; | ||||
| 	struct ast_region *old; | ||||
|  | ||||
| 	for (idx = 0; idx < ARRAY_LEN(freed->regions); ++idx) { | ||||
| 		old = freed->regions[idx]; | ||||
| 		if (old) { | ||||
| 			total_len += old->len; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return total_len; | ||||
| } | ||||
|  | ||||
| static char *handle_memory_atexit_list(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | ||||
| { | ||||
| 	switch (cmd) { | ||||
| @@ -765,12 +791,54 @@ static char *handle_memory_atexit_summary(struct ast_cli_entry *e, int cmd, stru | ||||
| 	return CLI_SUCCESS; | ||||
| } | ||||
|  | ||||
| /*! | ||||
|  * \internal | ||||
|  * \brief Common summary output at the end of the memory show commands. | ||||
|  * | ||||
|  * \param fd CLI output file descriptor. | ||||
|  * \param whales_len Accumulated size of free large allocations. | ||||
|  * \param minnows_len Accumulated size of free small allocations. | ||||
|  * \param total_len Accumulated size of all current allocations. | ||||
|  * \param selected_len Accumulated size of the selected allocations. | ||||
|  * \param cache_len Accumulated size of the allocations that are part of a cache. | ||||
|  * \param count Number of selected allocations. | ||||
|  * | ||||
|  * \return Nothing | ||||
|  */ | ||||
| static void print_memory_show_common_stats(int fd, | ||||
| 	unsigned int whales_len, | ||||
| 	unsigned int minnows_len, | ||||
| 	unsigned int total_len, | ||||
| 	unsigned int selected_len, | ||||
| 	unsigned int cache_len, | ||||
| 	unsigned int count) | ||||
| { | ||||
| 	if (cache_len) { | ||||
| 		ast_cli(fd, "%10u bytes allocated (%u in caches) in %u selected allocations\n\n", | ||||
| 			selected_len, cache_len, count); | ||||
| 	} else { | ||||
| 		ast_cli(fd, "%10u bytes allocated in %u selected allocations\n\n", | ||||
| 			selected_len, count); | ||||
| 	} | ||||
|  | ||||
| 	ast_cli(fd, "%10u bytes in all allocations\n", total_len); | ||||
| 	ast_cli(fd, "%10u bytes in deferred free large allocations\n", whales_len); | ||||
| 	ast_cli(fd, "%10u bytes in deferred free small allocations\n", minnows_len); | ||||
| 	ast_cli(fd, "%10u bytes in deferred free allocations\n", | ||||
| 		whales_len + minnows_len); | ||||
| 	ast_cli(fd, "%10u bytes in all allocations and deferred free allocations\n", | ||||
| 		total_len + whales_len + minnows_len); | ||||
| } | ||||
|  | ||||
| static char *handle_memory_show_allocations(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | ||||
| { | ||||
| 	const char *fn = NULL; | ||||
| 	struct ast_region *reg; | ||||
| 	unsigned int idx; | ||||
| 	unsigned int len = 0; | ||||
| 	unsigned int whales_len; | ||||
| 	unsigned int minnows_len; | ||||
| 	unsigned int total_len = 0; | ||||
| 	unsigned int selected_len = 0; | ||||
| 	unsigned int cache_len = 0; | ||||
| 	unsigned int count = 0; | ||||
|  | ||||
| @@ -804,6 +872,7 @@ static char *handle_memory_show_allocations(struct ast_cli_entry *e, int cmd, st | ||||
| 	ast_mutex_lock(®lock); | ||||
| 	for (idx = 0; idx < ARRAY_LEN(regions); ++idx) { | ||||
| 		for (reg = regions[idx]; reg; reg = AST_LIST_NEXT(reg, node)) { | ||||
| 			total_len += reg->len; | ||||
| 			if (fn && strcasecmp(fn, reg->file)) { | ||||
| 				continue; | ||||
| 			} | ||||
| @@ -814,21 +883,21 @@ static char *handle_memory_show_allocations(struct ast_cli_entry *e, int cmd, st | ||||
| 				(unsigned int) reg->len, reg->cache ? " (cache)" : "", | ||||
| 				reg->func, reg->lineno, reg->file); | ||||
|  | ||||
| 			len += reg->len; | ||||
| 			selected_len += reg->len; | ||||
| 			if (reg->cache) { | ||||
| 				cache_len += reg->len; | ||||
| 			} | ||||
| 			++count; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	whales_len = freed_regions_size(&whales); | ||||
| 	minnows_len = freed_regions_size(&minnows); | ||||
| 	ast_mutex_unlock(®lock); | ||||
|  | ||||
| 	if (cache_len) { | ||||
| 		ast_cli(a->fd, "%u bytes allocated (%u in caches) in %u allocations\n", | ||||
| 			len, cache_len, count); | ||||
| 	} else { | ||||
| 		ast_cli(a->fd, "%u bytes allocated in %u allocations\n", len, count); | ||||
| 	} | ||||
| 	print_memory_show_common_stats(a->fd, | ||||
| 		whales_len, minnows_len, total_len, | ||||
| 		selected_len, cache_len, count); | ||||
|  | ||||
| 	return CLI_SUCCESS; | ||||
| } | ||||
| @@ -841,7 +910,10 @@ static char *handle_memory_show_summary(struct ast_cli_entry *e, int cmd, struct | ||||
| 	int idx; | ||||
| 	int cmp; | ||||
| 	struct ast_region *reg; | ||||
| 	unsigned int len = 0; | ||||
| 	unsigned int whales_len; | ||||
| 	unsigned int minnows_len; | ||||
| 	unsigned int total_len = 0; | ||||
| 	unsigned int selected_len = 0; | ||||
| 	unsigned int cache_len = 0; | ||||
| 	unsigned int count = 0; | ||||
| 	struct file_summary { | ||||
| @@ -859,7 +931,7 @@ static char *handle_memory_show_summary(struct ast_cli_entry *e, int cmd, struct | ||||
| 		e->usage = | ||||
| 			"Usage: memory show summary [<file>]\n" | ||||
| 			"       Summarizes heap memory allocations by file, or optionally\n" | ||||
| 			"       by line, if a file is specified.\n"; | ||||
| 			"       by line if a file is specified.\n"; | ||||
| 		return NULL; | ||||
| 	case CLI_GENERATE: | ||||
| 		return NULL; | ||||
| @@ -874,6 +946,7 @@ static char *handle_memory_show_summary(struct ast_cli_entry *e, int cmd, struct | ||||
| 	ast_mutex_lock(®lock); | ||||
| 	for (idx = 0; idx < ARRAY_LEN(regions); ++idx) { | ||||
| 		for (reg = regions[idx]; reg; reg = AST_LIST_NEXT(reg, node)) { | ||||
| 			total_len += reg->len; | ||||
| 			if (fn) { | ||||
| 				if (strcasecmp(fn, reg->file)) { | ||||
| 					continue; | ||||
| @@ -932,11 +1005,14 @@ static char *handle_memory_show_summary(struct ast_cli_entry *e, int cmd, struct | ||||
| 			++cur->count; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	whales_len = freed_regions_size(&whales); | ||||
| 	minnows_len = freed_regions_size(&minnows); | ||||
| 	ast_mutex_unlock(®lock); | ||||
|  | ||||
| 	/* Dump the whole list */ | ||||
| 	for (cur = list; cur; cur = cur->next) { | ||||
| 		len += cur->len; | ||||
| 		selected_len += cur->len; | ||||
| 		cache_len += cur->cache_len; | ||||
| 		count += cur->count; | ||||
| 		if (cur->cache_len) { | ||||
| @@ -958,12 +1034,9 @@ static char *handle_memory_show_summary(struct ast_cli_entry *e, int cmd, struct | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (cache_len) { | ||||
| 		ast_cli(a->fd, "%u bytes allocated (%u in caches) in %u allocations\n", | ||||
| 			len, cache_len, count); | ||||
| 	} else { | ||||
| 		ast_cli(a->fd, "%u bytes allocated in %u allocations\n", len, count); | ||||
| 	} | ||||
| 	print_memory_show_common_stats(a->fd, | ||||
| 		whales_len, minnows_len, total_len, | ||||
| 		selected_len, cache_len, count); | ||||
|  | ||||
| 	return CLI_SUCCESS; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user