Add some very basic framework to fetch statistics of memory usage per component.
Use it in memory_dlg. svn path=/trunk/; revision=51069
This commit is contained in:
parent
0e90cd8f80
commit
1cabad610b
|
@ -33,10 +33,12 @@
|
||||||
|
|
||||||
#include "app_mem_usage.h"
|
#include "app_mem_usage.h"
|
||||||
|
|
||||||
gsize
|
#define MAX_COMPONENTS 16
|
||||||
get_total_mem_used_by_app(void)
|
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
static gsize
|
||||||
|
win32_get_total_mem_used_by_app(void)
|
||||||
|
{
|
||||||
HANDLE pHandle;
|
HANDLE pHandle;
|
||||||
PROCESS_MEMORY_COUNTERS pmc;
|
PROCESS_MEMORY_COUNTERS pmc;
|
||||||
SIZE_T workingSize = 0;
|
SIZE_T workingSize = 0;
|
||||||
|
@ -45,8 +47,6 @@ get_total_mem_used_by_app(void)
|
||||||
|
|
||||||
if (GetProcessMemoryInfo(pHandle, &pmc, sizeof(pmc))){
|
if (GetProcessMemoryInfo(pHandle, &pmc, sizeof(pmc))){
|
||||||
workingSize = pmc.WorkingSetSize;
|
workingSize = pmc.WorkingSetSize;
|
||||||
|
|
||||||
workingSize = workingSize / 1024;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(pHandle);
|
CloseHandle(pHandle);
|
||||||
|
@ -56,7 +56,70 @@ get_total_mem_used_by_app(void)
|
||||||
}else{
|
}else{
|
||||||
return (int)workingSize;
|
return (int)workingSize;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif /* (_WIN32) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define get_total_mem_used_by_app win32_get_total_mem_used_by_app
|
||||||
|
|
||||||
|
#endif /* (_WIN32) */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef get_total_mem_used_by_app
|
||||||
|
static const ws_mem_usage_t total_usage = { "Total", get_total_mem_used_by_app, NULL };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef get_rss_mem_used_by_app
|
||||||
|
static const ws_mem_usage_t rss_usage = { "RSS", get_rss_mem_used_by_app, NULL };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const ws_mem_usage_t *memory_components[MAX_COMPONENTS] = {
|
||||||
|
#ifdef get_total_mem_used_by_app
|
||||||
|
&total_usage,
|
||||||
|
#endif
|
||||||
|
#ifdef get_rss_mem_used_by_app
|
||||||
|
&rss_usage,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint memory_register_num = 0
|
||||||
|
#ifdef get_total_mem_used_by_app
|
||||||
|
+ 1
|
||||||
|
#endif
|
||||||
|
#ifdef get_rss_mem_used_by_app
|
||||||
|
+ 1
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
/* public API */
|
||||||
|
|
||||||
|
void
|
||||||
|
memory_usage_component_register(const ws_mem_usage_t *component)
|
||||||
|
{
|
||||||
|
if (memory_register_num >= MAX_COMPONENTS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memory_components[memory_register_num++] = component;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
memory_usage_get(guint index, gsize *value)
|
||||||
|
{
|
||||||
|
if (index >= memory_register_num)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
*value = memory_components[index]->fetch();
|
||||||
|
|
||||||
|
return memory_components[index]->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
memory_usage_gc(void)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < memory_register_num; i++) {
|
||||||
|
if (memory_components[i]->gc)
|
||||||
|
memory_components[i]->gc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,19 @@
|
||||||
#ifndef __APP_MEM_USAGE_H__
|
#ifndef __APP_MEM_USAGE_H__
|
||||||
#define __APP_MEM_USAGE_H__
|
#define __APP_MEM_USAGE_H__
|
||||||
|
|
||||||
gsize get_total_mem_used_by_app(void);
|
#include "ws_symbol_export.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
gsize (*fetch)(void);
|
||||||
|
void (*gc)(void);
|
||||||
|
|
||||||
|
} ws_mem_usage_t;
|
||||||
|
|
||||||
|
WS_DLL_PUBLIC void memory_usage_component_register(const ws_mem_usage_t *component);
|
||||||
|
|
||||||
|
WS_DLL_PUBLIC void memory_usage_gc(void);
|
||||||
|
|
||||||
|
WS_DLL_PUBLIC const char *memory_usage_get(guint index, gsize *value);
|
||||||
|
|
||||||
#endif /* APP_MEM_USAGE_H */
|
#endif /* APP_MEM_USAGE_H */
|
||||||
|
|
35
epan/emem.c
35
epan/emem.c
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "app_mem_usage.h"
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include "emem.h"
|
#include "emem.h"
|
||||||
#include "wmem/wmem.h"
|
#include "wmem/wmem.h"
|
||||||
|
@ -295,6 +296,26 @@ emem_init_chunk(emem_pool_t *mem)
|
||||||
mem->memory_alloc = emem_alloc_glib;
|
mem->memory_alloc = emem_alloc_glib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gsize
|
||||||
|
emem_memory_usage(const emem_pool_t *pool)
|
||||||
|
{
|
||||||
|
gsize total_used = 0;
|
||||||
|
emem_chunk_t *chunk;
|
||||||
|
|
||||||
|
for (chunk = pool->used_list; chunk; chunk = chunk->next)
|
||||||
|
total_used += (chunk->amount_free_init - chunk->amount_free);
|
||||||
|
|
||||||
|
for (chunk = pool->free_list; chunk; chunk = chunk->next)
|
||||||
|
total_used += (chunk->amount_free_init - chunk->amount_free);
|
||||||
|
|
||||||
|
return total_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gsize
|
||||||
|
ep_memory_usage(void)
|
||||||
|
{
|
||||||
|
return emem_memory_usage(&ep_packet_mem);
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the packet-lifetime memory allocation pool.
|
/* Initialize the packet-lifetime memory allocation pool.
|
||||||
* This function should be called only once when Wireshark or TShark starts
|
* This function should be called only once when Wireshark or TShark starts
|
||||||
|
@ -303,6 +324,8 @@ emem_init_chunk(emem_pool_t *mem)
|
||||||
static void
|
static void
|
||||||
ep_init_chunk(void)
|
ep_init_chunk(void)
|
||||||
{
|
{
|
||||||
|
static const ws_mem_usage_t ep_stats = { "EP", ep_memory_usage, NULL };
|
||||||
|
|
||||||
ep_packet_mem.free_list=NULL;
|
ep_packet_mem.free_list=NULL;
|
||||||
ep_packet_mem.used_list=NULL;
|
ep_packet_mem.used_list=NULL;
|
||||||
ep_packet_mem.trees=NULL; /* not used by this allocator */
|
ep_packet_mem.trees=NULL; /* not used by this allocator */
|
||||||
|
@ -316,6 +339,14 @@ ep_init_chunk(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
emem_init_chunk(&ep_packet_mem);
|
emem_init_chunk(&ep_packet_mem);
|
||||||
|
|
||||||
|
memory_usage_component_register(&ep_stats);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gsize
|
||||||
|
se_memory_usage(void)
|
||||||
|
{
|
||||||
|
return emem_memory_usage(&se_packet_mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the capture-lifetime memory allocation pool.
|
/* Initialize the capture-lifetime memory allocation pool.
|
||||||
|
@ -325,6 +356,8 @@ ep_init_chunk(void)
|
||||||
static void
|
static void
|
||||||
se_init_chunk(void)
|
se_init_chunk(void)
|
||||||
{
|
{
|
||||||
|
static const ws_mem_usage_t se_stats = { "SE", se_memory_usage, NULL };
|
||||||
|
|
||||||
se_packet_mem.free_list = NULL;
|
se_packet_mem.free_list = NULL;
|
||||||
se_packet_mem.used_list = NULL;
|
se_packet_mem.used_list = NULL;
|
||||||
se_packet_mem.trees = NULL;
|
se_packet_mem.trees = NULL;
|
||||||
|
@ -334,6 +367,8 @@ se_init_chunk(void)
|
||||||
se_packet_mem.debug_verify_pointers = (getenv("WIRESHARK_SE_VERIFY_POINTERS") != NULL);
|
se_packet_mem.debug_verify_pointers = (getenv("WIRESHARK_SE_VERIFY_POINTERS") != NULL);
|
||||||
|
|
||||||
emem_init_chunk(&se_packet_mem);
|
emem_init_chunk(&se_packet_mem);
|
||||||
|
|
||||||
|
memory_usage_component_register(&se_stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize all the allocators here.
|
/* Initialize all the allocators here.
|
||||||
|
|
|
@ -40,16 +40,9 @@
|
||||||
#include "epan/app_mem_usage.h"
|
#include "epan/app_mem_usage.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MEMORY_TOTAL = 0,
|
MAX_GRAPHS = 10
|
||||||
MEMORY_RSS,
|
|
||||||
MEMORY_EP,
|
|
||||||
MEMORY_SE,
|
|
||||||
|
|
||||||
MAX_GRAPHS
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *graph_labels[MAX_GRAPHS] = { "Total", "RSS", "EP", "SE" };
|
|
||||||
|
|
||||||
#define MAX_YSCALE 28
|
#define MAX_YSCALE 28
|
||||||
static guint32 yscale_max[MAX_YSCALE] = {0, 1, 10, 20,
|
static guint32 yscale_max[MAX_YSCALE] = {0, 1, 10, 20,
|
||||||
50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000,
|
50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000,
|
||||||
|
@ -595,9 +588,13 @@ create_filter_area(io_stat_t *io, GtkWidget *box)
|
||||||
gtk_widget_show(hbox);
|
gtk_widget_show(hbox);
|
||||||
|
|
||||||
for (i=0; i<MAX_GRAPHS; i++) {
|
for (i=0; i<MAX_GRAPHS; i++) {
|
||||||
|
const char *label = memory_usage_get(i, NULL);
|
||||||
GtkWidget *display_button;
|
GtkWidget *display_button;
|
||||||
|
|
||||||
display_button = gtk_toggle_button_new_with_label(graph_labels[i]);
|
if (!label)
|
||||||
|
break;
|
||||||
|
|
||||||
|
display_button = gtk_toggle_button_new_with_label(label);
|
||||||
gtk_box_pack_start(GTK_BOX(hbox), display_button, FALSE, FALSE, 0);
|
gtk_box_pack_start(GTK_BOX(hbox), display_button, FALSE, FALSE, 0);
|
||||||
g_signal_connect(display_button, "toggled", G_CALLBACK(filter_callback), &io->graphs[i]);
|
g_signal_connect(display_button, "toggled", G_CALLBACK(filter_callback), &io->graphs[i]);
|
||||||
gtk_widget_show(display_button);
|
gtk_widget_show(display_button);
|
||||||
|
@ -647,13 +644,10 @@ init_io_stat_window(io_stat_t *io)
|
||||||
static gboolean
|
static gboolean
|
||||||
call_it(gpointer user_data)
|
call_it(gpointer user_data)
|
||||||
{
|
{
|
||||||
gsize ep_memory_usage(void);
|
|
||||||
gsize se_memory_usage(void);
|
|
||||||
io_stat_t *io = (io_stat_t *) user_data;
|
io_stat_t *io = (io_stat_t *) user_data;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
int idx, i;
|
||||||
int idx;
|
|
||||||
|
|
||||||
io->needs_redraw = TRUE;
|
io->needs_redraw = TRUE;
|
||||||
|
|
||||||
|
@ -665,24 +659,20 @@ gsize se_memory_usage(void);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Point to the appropriate io_item_t struct */
|
|
||||||
io->graphs[MEMORY_TOTAL].items[idx]->bytes = get_total_mem_used_by_app() * 1000;
|
|
||||||
tmp = format_size(io->graphs[MEMORY_TOTAL].items[idx]->bytes, format_size_unit_bytes);
|
|
||||||
g_snprintf(buf, sizeof(buf), "Total [%s]", tmp);
|
|
||||||
gtk_button_set_label(GTK_BUTTON(io->graphs[MEMORY_TOTAL].display_button), buf);
|
|
||||||
g_free(tmp);
|
|
||||||
|
|
||||||
io->graphs[MEMORY_EP].items[idx]->bytes = ep_memory_usage();
|
for (i = 0; i < MAX_GRAPHS; i++) {
|
||||||
tmp = format_size(io->graphs[MEMORY_EP].items[idx]->bytes, format_size_unit_bytes);
|
const char *label;
|
||||||
g_snprintf(buf, sizeof(buf), "EP [%s]", tmp);
|
|
||||||
gtk_button_set_label(GTK_BUTTON(io->graphs[MEMORY_EP].display_button), buf);
|
|
||||||
g_free(tmp);
|
|
||||||
|
|
||||||
io->graphs[MEMORY_SE].items[idx]->bytes = se_memory_usage();
|
label = memory_usage_get(i, &io->graphs[i].items[idx]->bytes);
|
||||||
tmp = format_size(io->graphs[MEMORY_SE].items[idx]->bytes, format_size_unit_bytes);
|
|
||||||
g_snprintf(buf, sizeof(buf), "SE [%s]", tmp);
|
if (!label)
|
||||||
gtk_button_set_label(GTK_BUTTON(io->graphs[MEMORY_SE].display_button), buf);
|
break;
|
||||||
g_free(tmp);
|
|
||||||
|
tmp = format_size(io->graphs[i].items[idx]->bytes, format_size_unit_bytes);
|
||||||
|
g_snprintf(buf, sizeof(buf), "%s [%s]", label, tmp);
|
||||||
|
gtk_button_set_label(GTK_BUTTON(io->graphs[i].display_button), buf);
|
||||||
|
g_free(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
io_stat_draw(io);
|
io_stat_draw(io);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue