summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira TAGOH <akira@tagoh.org>2006-06-14 16:52:37 +0000
committerAkira TAGOH <akira@tagoh.org>2006-06-14 16:52:37 +0000
commitf06aa99b6e440e4e9c4c079b72f8a8fca26dca18 (patch)
tree11bd6bde7588580e0e0b28d2e59cd91950a2e5a9
parentdbbc12074d9285366ca3fe5f90f7406103c9df5f (diff)
* src/visualizer.c (hg_memory_visualizer_real_size_allocate):
implemented. (hg_memory_visualizer_real_realize): implemented. (hg_memory_visualizer_real_expose): implemented. (hg_memory_visualizer_class_init): added draw-updated signal. (hg_memory_visualizer_real_unrealize): implemented. (_hg_memory_visualizer_idle_handler_cb): update a pixmap. (_hg_memory_visualizer_create_gc): new function. (_hg_memory_visualizer_redraw_in_pixmap): new function. (hg_memory_visualizer_get_used_size): new function. (hg_memory_visualizer_get_current_pool_name): new function. * src/hgspy.c (_hgspy_draw_updated_cb): new function. (_hgspy_update_vm_status): new function. (main): add widgets for memory informations. * src/hgspy_helper.c (helper_init): get an original function pointer for hg_mem_resize. (hg_mem_alloc_with_flags): check null. (hg_mem_free): fixed a typo. (hg_mem_resize): new function. need to watch this function too.
-rw-r--r--ChangeLog22
-rw-r--r--hieroglyph/version.h.in2
-rw-r--r--src/hgspy.c98
-rw-r--r--src/hgspy_helper.c61
-rw-r--r--src/visualizer.c302
-rw-r--r--src/visualizer.h39
6 files changed, 438 insertions, 86 deletions
diff --git a/ChangeLog b/ChangeLog
index a261a27..6b15a4e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
2006-06-15 Akira TAGOH <at@gclab.org>
+ * src/visualizer.c (hg_memory_visualizer_real_size_allocate):
+ implemented.
+ (hg_memory_visualizer_real_realize): implemented.
+ (hg_memory_visualizer_real_expose): implemented.
+ (hg_memory_visualizer_class_init): added draw-updated signal.
+ (hg_memory_visualizer_real_unrealize): implemented.
+ (_hg_memory_visualizer_idle_handler_cb): update a pixmap.
+ (_hg_memory_visualizer_create_gc): new function.
+ (_hg_memory_visualizer_redraw_in_pixmap): new function.
+ (hg_memory_visualizer_get_used_size): new function.
+ (hg_memory_visualizer_get_current_pool_name): new function.
+
+ * src/hgspy.c (_hgspy_draw_updated_cb): new function.
+ (_hgspy_update_vm_status): new function.
+ (main): add widgets for memory informations.
+
+ * src/hgspy_helper.c (helper_init): get an original function pointer
+ for hg_mem_resize.
+ (hg_mem_alloc_with_flags): check null.
+ (hg_mem_free): fixed a typo.
+ (hg_mem_resize): new function. need to watch this function too.
+
* examples/pse.c (main): invoke HG_MEM_INIT before doing anything.
* hieroglyph/hgvaluenode.h (HG_VALUE_SET_VALUE_NODE): check null.
diff --git a/hieroglyph/version.h.in b/hieroglyph/version.h.in
index beb06f6..c2368cc 100644
--- a/hieroglyph/version.h.in
+++ b/hieroglyph/version.h.in
@@ -29,7 +29,7 @@
G_BEGIN_DECLS
#define HIEROGLYPH_VERSION "@VERSION@"
-#define HIEROGLYPH_UUID "fb1a2e6a-3f22-451e-81b8-b3391d363eb1"
+#define HIEROGLYPH_UUID "ab6b8bed-b07b-45cc-a6ed-478cbee111bd"
const char *__hg_rcsid G_GNUC_UNUSED = "$Rev$";
diff --git a/src/hgspy.c b/src/hgspy.c
index 43360c0..0c4d56e 100644
--- a/src/hgspy.c
+++ b/src/hgspy.c
@@ -36,12 +36,19 @@ typedef struct _HieroGlyphSpy HgSpy;
struct _HieroGlyphSpy {
GtkWidget *window;
GtkWidget *visualizer;
+ GtkWidget *total_vm_size;
+ GtkWidget *used_vm_size;
+ GtkWidget *free_vm_size;
GtkUIManager *ui;
GThread *vm_thread;
LibrettoVM *vm;
gchar *file;
};
+static void _hgspy_update_vm_status(HgMemoryVisualizer *visual,
+ HgSpy *spy,
+ const gchar *name);
+
static gpointer __hg_spy_helper_get_widget = NULL;
/*
@@ -226,6 +233,47 @@ _hgspy_pool_updated_cb(HgMemoryVisualizer *visual,
gtk_menu_item_set_submenu(GTK_MENU_ITEM (bin), menu);
}
+static void
+_hgspy_draw_updated_cb(HgMemoryVisualizer *visual,
+ gpointer data)
+{
+ HgSpy *spy = data;
+ const gchar *name;
+
+ g_return_if_fail (HG_IS_MEMORY_VISUALIZER (visual));
+ g_return_if_fail (data != NULL);
+
+ name = hg_memory_visualizer_get_current_pool_name(visual);
+ if (name) {
+ _hgspy_update_vm_status(visual, spy, name);
+ }
+}
+
+static void
+_hgspy_update_vm_status(HgMemoryVisualizer *visual,
+ HgSpy *spy,
+ const gchar *name)
+{
+ gsize total, used;
+ gchar *p;
+
+ g_return_if_fail (HG_IS_MEMORY_VISUALIZER (visual));
+ g_return_if_fail (spy != NULL);
+ g_return_if_fail (name != NULL);
+
+ total = hg_memory_visualizer_get_max_size(visual, name);
+ p = g_strdup_printf("%d", total);
+ gtk_entry_set_text(GTK_ENTRY (spy->total_vm_size), p);
+ g_free(p);
+ used = hg_memory_visualizer_get_used_size(visual, name);
+ p = g_strdup_printf("%d", used);
+ gtk_entry_set_text(GTK_ENTRY (spy->used_vm_size), p);
+ g_free(p);
+ p = g_strdup_printf("%d", total - used);
+ gtk_entry_set_text(GTK_ENTRY (spy->free_vm_size), p);
+ g_free(p);
+}
+
/*
* Public Functions
*/
@@ -235,7 +283,7 @@ main(int argc,
{
GModule *module;
HgSpy *spy;
- GtkWidget *menubar, *vbox, *none;
+ GtkWidget *menubar, *vbox, *none, *table, *label;
GtkActionGroup *actions;
GtkActionEntry action_entries[] = {
/* toplevel menu */
@@ -335,6 +383,7 @@ main(int argc,
" </menu>"
" </menubar>"
"</ui>";
+ guint i = 0;
if ((module = g_module_open("libhgspy-helper.so", 0)) == NULL) {
g_warning("Failed g_module_open: %s", g_module_error());
@@ -363,6 +412,10 @@ main(int argc,
actions = gtk_action_group_new("MenuBar");
spy->ui = gtk_ui_manager_new();
vbox = gtk_vbox_new(FALSE, 0);
+ table = gtk_table_new(3, 2, FALSE);
+ spy->total_vm_size = gtk_entry_new();
+ spy->used_vm_size = gtk_entry_new();
+ spy->free_vm_size = gtk_entry_new();
spy->visualizer = ((GtkWidget * (*) (void))__hg_spy_helper_get_widget) ();
if (spy->visualizer == NULL) {
@@ -383,6 +436,12 @@ main(int argc,
gtk_ui_manager_insert_action_group(spy->ui, actions, 0);
none = gtk_ui_manager_get_widget(spy->ui, "/MenuBar/ViewMenu/PoolMenu/PoolNone");
gtk_widget_set_sensitive(none, FALSE);
+ gtk_editable_set_editable(GTK_EDITABLE (spy->total_vm_size), FALSE);
+ gtk_editable_set_editable(GTK_EDITABLE (spy->used_vm_size), FALSE);
+ gtk_editable_set_editable(GTK_EDITABLE (spy->free_vm_size), FALSE);
+ GTK_WIDGET_UNSET_FLAGS (spy->total_vm_size, GTK_CAN_FOCUS);
+ GTK_WIDGET_UNSET_FLAGS (spy->used_vm_size, GTK_CAN_FOCUS);
+ GTK_WIDGET_UNSET_FLAGS (spy->free_vm_size, GTK_CAN_FOCUS);
/* setup accelerators */
gtk_window_add_accel_group(GTK_WINDOW (spy->window), gtk_ui_manager_get_accel_group(spy->ui));
@@ -391,11 +450,48 @@ main(int argc,
menubar = gtk_ui_manager_get_widget(spy->ui, "/MenuBar");
gtk_box_pack_start(GTK_BOX (vbox), menubar, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX (vbox), spy->visualizer, TRUE, TRUE, 0);
+ /* total */
+ label = gtk_label_new(_("Total memory size:"));
+ gtk_table_attach(GTK_TABLE (table), label,
+ 0, 1, i, i + 1,
+ 0, GTK_FILL,
+ 0, 0);
+ gtk_table_attach(GTK_TABLE (table), spy->total_vm_size,
+ 1, 2, i, i + 1,
+ GTK_FILL | GTK_EXPAND, GTK_FILL,
+ 0, 0);
+ i++;
+ /* used */
+ label = gtk_label_new(_("Used memory size:"));
+ gtk_table_attach(GTK_TABLE (table), label,
+ 0, 1, i, i + 1,
+ 0, GTK_FILL,
+ 0, 0);
+ gtk_table_attach(GTK_TABLE (table), spy->used_vm_size,
+ 1, 2, i, i + 1,
+ GTK_FILL | GTK_EXPAND, GTK_FILL,
+ 0, 0);
+ i++;
+ /* free */
+ label = gtk_label_new(_("Free memory size:"));
+ gtk_table_attach(GTK_TABLE (table), label,
+ 0, 1, i, i + 1,
+ 0, GTK_FILL,
+ 0, 0);
+ gtk_table_attach(GTK_TABLE (table), spy->free_vm_size,
+ 1, 2, i, i + 1,
+ GTK_FILL | GTK_EXPAND, GTK_FILL,
+ 0, 0);
+ i++;
+
+ gtk_box_pack_end(GTK_BOX (vbox), table, FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER (spy->window), vbox);
/* setup signals */
g_signal_connect(spy->visualizer, "pool-updated",
G_CALLBACK (_hgspy_pool_updated_cb), spy);
+ g_signal_connect(spy->visualizer, "draw-updated",
+ G_CALLBACK (_hgspy_draw_updated_cb), spy);
g_signal_connect(spy->window, "delete-event",
G_CALLBACK (gtk_main_quit), NULL);
diff --git a/src/hgspy_helper.c b/src/hgspy_helper.c
index 70bf34e..14ac3ae 100644
--- a/src/hgspy_helper.c
+++ b/src/hgspy_helper.c
@@ -35,6 +35,7 @@
static gpointer __hg_mem_pool_add_heap = NULL;
static gpointer __hg_mem_alloc_with_flags = NULL;
static gpointer __hg_mem_free = NULL;
+static gpointer __hg_mem_resize = NULL;
static GModule *__handle = NULL;
static GtkWidget *visual = NULL;
@@ -62,6 +63,10 @@ helper_init(void)
g_warning("Failed g_module_symbol: %s", g_module_error());
exit(1);
}
+ if (!g_module_symbol(__handle, "hg_mem_resize", &__hg_mem_resize)) {
+ g_warning("Failed g_module_symbol: %s", g_module_error());
+ exit(1);
+ }
g_type_init();
visual = hg_memory_visualizer_new();
}
@@ -95,7 +100,30 @@ hg_mem_alloc_with_flags(HgMemPool *pool,
__hg_mem_alloc_with_flags) (pool, size, flags);
HgMemObject *obj;
- hg_mem_get_object__inline(retval, obj);
+ if (retval) {
+ hg_mem_get_object__inline(retval, obj);
+ if (obj) {
+ gint heap_id = HG_MEMOBJ_GET_HEAP_ID (obj);
+ HgHeap *h = g_ptr_array_index(obj->pool->heap_list, heap_id);
+
+ hg_memory_visualizer_set_chunk_state(HG_MEMORY_VISUALIZER (visual),
+ hg_mem_pool_get_name(obj->pool),
+ heap_id,
+ (gsize)obj - (gsize)h->heaps,
+ hg_mem_get_object_size(retval),
+ HG_CHUNK_USED);
+ }
+ }
+
+ return retval;
+}
+
+gboolean
+hg_mem_free(gpointer data)
+{
+ HgMemObject *obj;
+
+ hg_mem_get_object__inline(data, obj);
if (obj) {
gint heap_id = HG_MEMOBJ_GET_HEAP_ID (obj);
HgHeap *h = g_ptr_array_index(obj->pool->heap_list, heap_id);
@@ -104,16 +132,18 @@ hg_mem_alloc_with_flags(HgMemPool *pool,
hg_mem_pool_get_name(obj->pool),
heap_id,
(gsize)obj - (gsize)h->heaps,
- hg_mem_get_object_size(retval),
- HG_CHUNK_USED);
+ hg_mem_get_object_size(data),
+ HG_CHUNK_FREE);
}
- return retval;
+ return ((gboolean (*) (gpointer))__hg_mem_free) (data);
}
-gboolean
-hg_mem_free(gpointer data)
+gpointer
+hg_mem_resize(gpointer data,
+ gsize size)
{
+ gpointer retval;
HgMemObject *obj;
hg_mem_get_object__inline(data, obj);
@@ -129,7 +159,24 @@ hg_mem_free(gpointer data)
HG_CHUNK_FREE);
}
- return ((gboolean (*) (gpointer))__hg_mem_free) (data);
+ retval = ((gpointer (*) (gpointer, gsize))__hg_mem_resize) (data, size);
+
+ if (retval) {
+ hg_mem_get_object__inline(retval, obj);
+ if (obj) {
+ gint heap_id = HG_MEMOBJ_GET_HEAP_ID (obj);
+ HgHeap *h = g_ptr_array_index(obj->pool->heap_list, heap_id);
+
+ hg_memory_visualizer_set_chunk_state(HG_MEMORY_VISUALIZER (visual),
+ hg_mem_pool_get_name(obj->pool),
+ heap_id,
+ (gsize)obj - (gsize)h->heaps,
+ hg_mem_get_object_size(retval),
+ HG_CHUNK_USED);
+ }
+ }
+
+ return retval;
}
/*
diff --git a/src/visualizer.c b/src/visualizer.c
index 1a80895..10175a7 100644
--- a/src/visualizer.c
+++ b/src/visualizer.c
@@ -38,14 +38,16 @@ enum {
enum {
POOL_UPDATED,
+ DRAW_UPDATED,
LAST_SIGNAL
};
struct _HgMemoryVisualizerClass {
- GtkLayoutClass parent_class;
+ GtkMiscClass parent_class;
void (* pool_updated) (HgMemoryVisualizer *visual,
gpointer list);
+ void (* draw_updated) (HgMemoryVisualizer *visual);
};
struct Heap2Offset {
@@ -56,28 +58,36 @@ struct Heap2Offset {
};
struct _HgMemoryVisualizer {
- GtkLayout parent_instance;
+ GtkMisc parent_instance;
/*< private >*/
gdouble block_size;
- GHashTable *pool2size;
+ GHashTable *pool2total_size;
+ GHashTable *pool2used_size;
GHashTable *pool2array;
GSList *pool_name_list;
const gchar *current_pool_name;
struct Heap2Offset *current_h2o;
gboolean need_update;
guint idle_id;
+ GdkGC *bg_gc;
+ GdkGC *used_gc;
+ GdkGC *free_gc;
+ GdkGC *used_and_free_gc;
+ GdkPixmap *pixmap;
};
-static struct Heap2Offset *_heap2offset_new (guint prealloc);
-static void _heap2offset_free (gpointer data);
-static void _hg_memory_visualizer_add_idle (HgMemoryVisualizer *visual);
-static void _hg_memory_visualizer_remove_idle(HgMemoryVisualizer *visual);
+static struct Heap2Offset *_heap2offset_new (guint prealloc);
+static void _heap2offset_free (gpointer data);
+static void _hg_memory_visualizer_add_idle (HgMemoryVisualizer *visual);
+static void _hg_memory_visualizer_remove_idle (HgMemoryVisualizer *visual);
+static void _hg_memory_visualizer_create_gc (HgMemoryVisualizer *visual);
+static void _hg_memory_visualizer_redraw_in_pixmap(HgMemoryVisualizer *visual);
-static GtkLayoutClass *parent_class = NULL;
-static guint signals[LAST_SIGNAL] = { 0 };
+static GtkMiscClass *parent_class = NULL;
+static guint signals[LAST_SIGNAL] = { 0 };
G_LOCK_DEFINE_STATIC (visualizer);
@@ -130,17 +140,42 @@ hg_memory_visualizer_real_destroy(GtkObject *object)
g_return_if_fail (HG_IS_MEMORY_VISUALIZER (object));
visual = HG_MEMORY_VISUALIZER (object);
- if (visual->pool2size) {
- g_hash_table_destroy(visual->pool2size);
- visual->pool2size = NULL;
+ if (visual->pool2total_size) {
+ g_hash_table_destroy(visual->pool2total_size);
+ visual->pool2total_size = NULL;
+ }
+ if (visual->pool2used_size) {
+ g_hash_table_destroy(visual->pool2used_size);
+ visual->pool2used_size = NULL;
}
if (visual->pool2array) {
g_hash_table_destroy(visual->pool2array);
visual->pool2array = NULL;
}
+ if (visual->pool_name_list) {
+ g_slist_free(visual->pool_name_list);
+ visual->pool_name_list = NULL;
+ }
+ visual->current_pool_name = NULL;
+ visual->current_h2o = NULL;
_hg_memory_visualizer_remove_idle(visual);
- /* FIXME: not yet implemented */
+ if (visual->bg_gc) {
+ g_object_unref(visual->bg_gc);
+ visual->bg_gc = NULL;
+ }
+ if (visual->used_gc) {
+ g_object_unref(visual->used_gc);
+ visual->used_gc = NULL;
+ }
+ if (visual->free_gc) {
+ g_object_unref(visual->free_gc);
+ visual->free_gc = NULL;
+ }
+ if (visual->used_and_free_gc) {
+ g_object_unref(visual->used_and_free_gc);
+ visual->used_and_free_gc = NULL;
+ }
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
@@ -167,16 +202,7 @@ hg_memory_visualizer_real_size_allocate(GtkWidget *widget,
(* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation);
visual = HG_MEMORY_VISUALIZER (widget);
-
- visual->parent_instance.hadjustment->page_size = allocation->width;
- visual->parent_instance.hadjustment->page_increment = allocation->width / 2;
- visual->parent_instance.vadjustment->page_size = allocation->height;
- visual->parent_instance.vadjustment->page_increment = allocation->height / 2;
-
- /* FIXME: scroll */
-
- g_signal_emit_by_name(visual->parent_instance.hadjustment, "changed");
- g_signal_emit_by_name(visual->parent_instance.vadjustment, "changed");
+ _hg_memory_visualizer_redraw_in_pixmap(visual);
}
static void
@@ -191,13 +217,15 @@ hg_memory_visualizer_real_realize(GtkWidget *widget)
visual = HG_MEMORY_VISUALIZER (widget);
- gdk_window_set_events(visual->parent_instance.bin_window,
- (gdk_window_get_events(visual->parent_instance.bin_window)
- | GDK_EXPOSURE_MASK));
-
- g_print("realize\n");
- /* FIXME: not yet implemented */
+ widget->style = gtk_style_attach(widget->style, widget->window);
+ gdk_window_set_background(widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]);
+ if (visual->bg_gc == NULL ||
+ visual->used_gc == NULL ||
+ visual->free_gc == NULL ||
+ visual->used_and_free_gc == NULL)
+ _hg_memory_visualizer_create_gc(visual);
+ _hg_memory_visualizer_redraw_in_pixmap(visual);
}
static void
@@ -210,6 +238,23 @@ hg_memory_visualizer_real_unrealize(GtkWidget *widget)
visual = HG_MEMORY_VISUALIZER (widget);
_hg_memory_visualizer_remove_idle(visual);
+
+ if (visual->bg_gc) {
+ g_object_unref(visual->bg_gc);
+ visual->bg_gc = NULL;
+ }
+ if (visual->used_gc) {
+ g_object_unref(visual->used_gc);
+ visual->used_gc = NULL;
+ }
+ if (visual->free_gc) {
+ g_object_unref(visual->free_gc);
+ visual->free_gc = NULL;
+ }
+ if (visual->used_and_free_gc) {
+ g_object_unref(visual->used_and_free_gc);
+ visual->used_and_free_gc = NULL;
+ }
g_print("unrealize\n");
/* FIXME: not yet implemented */
@@ -231,10 +276,6 @@ hg_memory_visualizer_real_map(GtkWidget *widget)
if (visual->need_update)
_hg_memory_visualizer_add_idle(visual);
-
- g_print("map\n");
- /* FIXME: not yet implemented */
-
}
static void
@@ -247,8 +288,6 @@ hg_memory_visualizer_real_unmap(GtkWidget *widget)
visual = HG_MEMORY_VISUALIZER (widget);
_hg_memory_visualizer_remove_idle(visual);
- g_print("unmap\n");
- /* FIXME: not yet implemented */
if (GTK_WIDGET_CLASS (parent_class)->unmap)
(* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
@@ -259,17 +298,23 @@ hg_memory_visualizer_real_expose(GtkWidget *widget,
GdkEventExpose *event)
{
HgMemoryVisualizer *visual;
+ GtkMisc *misc;
g_return_val_if_fail (HG_IS_MEMORY_VISUALIZER (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
+ misc = GTK_MISC (widget);
visual = HG_MEMORY_VISUALIZER (widget);
- if (!GTK_WIDGET_DRAWABLE (widget) || (event->window != visual->parent_instance.bin_window))
+ if (!GTK_WIDGET_MAPPED (widget))
return FALSE;
- g_print("expose\n");
- /* FIXME: not yet implemented */
+ gdk_draw_drawable(widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+ visual->pixmap,
+ event->area.x, event->area.y,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
return FALSE;
}
@@ -324,19 +369,31 @@ hg_memory_visualizer_class_init(HgMemoryVisualizerClass *klass)
gtk_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
+ signals[DRAW_UPDATED] = g_signal_new("draw-updated",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (HgMemoryVisualizerClass, draw_updated),
+ NULL, NULL,
+ gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
hg_memory_visualizer_instance_init(HgMemoryVisualizer *visual)
{
- visual->block_size = 0.0L;
- visual->pool2size = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ visual->pool2total_size = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ visual->pool2used_size = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
visual->pool2array = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _heap2offset_free);
visual->pool_name_list = NULL;
visual->current_pool_name = NULL;
visual->current_h2o = NULL;
visual->need_update = FALSE;
visual->idle_id = 0;
+ visual->bg_gc = NULL;
+ visual->used_gc = NULL;
+ visual->free_gc = NULL;
+ visual->used_and_free_gc = NULL;
+ visual->pixmap = NULL;
}
static struct Heap2Offset *
@@ -374,15 +431,19 @@ _hg_memory_visualizer_idle_handler_cb(gpointer data)
{
HgMemoryVisualizer *visual;
+ visual = HG_MEMORY_VISUALIZER (data);
+ _hg_memory_visualizer_redraw_in_pixmap(visual);
+
G_LOCK (visualizer);
- visual = HG_MEMORY_VISUALIZER (data);
gtk_widget_queue_draw(GTK_WIDGET (visual));
visual->idle_id = 0;
visual->need_update = FALSE;
G_UNLOCK (visualizer);
+ g_signal_emit(visual, signals[DRAW_UPDATED], 0);
+
return FALSE;
}
@@ -405,6 +466,116 @@ _hg_memory_visualizer_remove_idle(HgMemoryVisualizer *visual)
}
}
+static void
+_hg_memory_visualizer_create_gc(HgMemoryVisualizer *visual)
+{
+ GdkGCValues values;
+
+ gdk_color_black(gdk_colormap_get_system(), &values.background);
+ visual->bg_gc = gdk_gc_new_with_values(GTK_WIDGET (visual)->window, &values,
+ GDK_GC_BACKGROUND);
+ values.foreground.pixel = 0;
+ values.foreground.red = 0;
+ values.foreground.green = 0;
+ values.foreground.blue = 32768;
+ gdk_colormap_alloc_color(gdk_colormap_get_system(), &values.foreground, FALSE, FALSE);
+ visual->free_gc = gdk_gc_new_with_values(GTK_WIDGET (visual)->window, &values,
+ GDK_GC_FOREGROUND);
+ values.foreground.pixel = 0;
+ values.foreground.red = 32768;
+ values.foreground.green = 0;
+ values.foreground.blue = 0;
+ gdk_colormap_alloc_color(gdk_colormap_get_system(), &values.foreground, FALSE, FALSE);
+ visual->used_gc = gdk_gc_new_with_values(GTK_WIDGET (visual)->window, &values,
+ GDK_GC_FOREGROUND);
+ values.foreground.pixel = 0;
+ values.foreground.red = 32768;
+ values.foreground.green = 0;
+ values.foreground.blue = 32768;
+ gdk_colormap_alloc_color(gdk_colormap_get_system(), &values.foreground, FALSE, FALSE);
+ visual->used_and_free_gc = gdk_gc_new_with_values(GTK_WIDGET (visual)->window, &values,
+ GDK_GC_FOREGROUND);
+}
+
+static void
+_hg_memory_visualizer_redraw_in_pixmap(HgMemoryVisualizer *visual)
+{
+ GtkWidget *widget = GTK_WIDGET (visual);
+ GtkMisc *misc = GTK_MISC (visual);
+ gint i, j, base_x, base_y, x, y, width, height, base_scale, block_size, area;
+
+ if (GTK_WIDGET_REALIZED (widget)) {
+ G_LOCK (visualizer);
+
+ if (visual->pixmap)
+ g_object_unref(G_OBJECT (visual->pixmap));
+ visual->pixmap = gdk_pixmap_new(widget->window,
+ widget->allocation.width,
+ widget->allocation.height,
+ -1);
+ base_x = x = misc->xpad;
+ base_y = y = misc->ypad;
+ width = widget->allocation.width - misc->xpad;
+ height = widget->allocation.height - misc->ypad;
+ area = (gdouble)(width - base_x) * (gdouble)(height - base_y);
+ /* draw a background */
+ gdk_draw_rectangle(visual->pixmap,
+ visual->bg_gc,
+ TRUE,
+ x, y, width, height);
+ /* draw a memory images */
+ if (visual->current_h2o) {
+ struct Heap2Offset *h2o = visual->current_h2o;
+ gint _used = 0, _free = 0, _scale;
+ GdkGC *gc;
+
+ if (area >= h2o->total_size) {
+ block_size = (gint)sqrt(area / h2o->total_size);
+ base_scale = 1;
+ } else {
+ base_scale = (gint)(1 / sqrt((gdouble)area / (gdouble)h2o->total_size));
+ base_scale *= base_scale;
+ block_size = 1;
+ }
+ _scale = base_scale;
+ for (i = 0; i < h2o->total_size / 8; i++) {
+ for (j = 7; j >= 0; j--) {
+ if ((x + block_size) > width) {
+ x = base_x;
+ y += block_size;
+ }
+ if ((h2o->bitmaps[i] & (1 << j)) != 0) {
+ _used++;
+ } else {
+ _free++;
+ }
+ _scale--;
+ if (_scale == 0) {
+ if (_used > 0 && _free == 0)
+ gc = visual->used_gc;
+ else if (_used == 0 && _free > 0)
+ gc = visual->free_gc;
+ else
+ gc = visual->used_and_free_gc;
+ gdk_draw_rectangle(visual->pixmap,
+ gc,
+ TRUE,
+ x, y,
+ block_size, block_size);
+ x += block_size;
+ _scale = base_scale;
+ _used = 0;
+ _free = 0;
+ }
+ }
+ }
+ }
+ visual->need_update = TRUE;
+ _hg_memory_visualizer_add_idle(visual);
+ G_UNLOCK (visualizer);
+ }
+}
+
/*
* Public Functions
*/
@@ -427,7 +598,7 @@ hg_memory_visualizer_get_type(void)
.value_table = NULL,
};
- mv_type = g_type_register_static(GTK_TYPE_LAYOUT, "HgMemoryVisualizer",
+ mv_type = g_type_register_static(GTK_TYPE_MISC, "HgMemoryVisualizer",
&mv_info, 0);
}
@@ -445,15 +616,12 @@ hg_memory_visualizer_set_max_size(HgMemoryVisualizer *visual,
const gchar *name,
gsize size)
{
- gsize area;
- gdouble scale;
struct Heap2Offset *h2o;
g_return_if_fail (HG_IS_MEMORY_VISUALIZER (visual));
g_return_if_fail (name != NULL);
- area = visual->parent_instance.width * visual->parent_instance.height;
- g_hash_table_insert(visual->pool2size, g_strdup(name), GSIZE_TO_POINTER (size));
+ g_hash_table_insert(visual->pool2total_size, g_strdup(name), GSIZE_TO_POINTER (size));
if ((h2o = g_hash_table_lookup(visual->pool2array, name)) == NULL) {
h2o = _heap2offset_new(256);
g_hash_table_insert(visual->pool2array, g_strdup(name), h2o);
@@ -472,12 +640,6 @@ hg_memory_visualizer_set_max_size(HgMemoryVisualizer *visual,
h2o->bitmaps = g_new0(gchar, (size + 8) / 8);
}
h2o->total_size = size;
- if (area > size) {
- scale = area / size;
- visual->block_size = sqrt(scale);
- } else {
- /* FIXME: need to scale up to fit in */
- }
}
gsize
@@ -487,7 +649,7 @@ hg_memory_visualizer_get_max_size(HgMemoryVisualizer *visual,
g_return_val_if_fail (HG_IS_MEMORY_VISUALIZER (visual), 0);
g_return_val_if_fail (name != NULL, 0);
- return GPOINTER_TO_SIZE (g_hash_table_lookup(visual->pool2size, name));
+ return GPOINTER_TO_SIZE (g_hash_table_lookup(visual->pool2total_size, name));
}
void
@@ -538,7 +700,7 @@ hg_memory_visualizer_set_chunk_state(HgMemoryVisualizer *visual,
HgMemoryChunkState state)
{
struct Heap2Offset *h2o;
- gsize base, location, start, end, i;
+ gsize base, location, start, end, i, used_size;
gint bit;
g_return_if_fail (HG_IS_MEMORY_VISUALIZER (visual));
@@ -552,21 +714,30 @@ hg_memory_visualizer_set_chunk_state(HgMemoryVisualizer *visual,
base = h2o->heap2offset[heap_id];
start = base + offset;
end = start + size;
+
+ G_LOCK (visualizer);
+
+ used_size = hg_memory_visualizer_get_used_size(visual, name);
for (i = start; i < end; i++) {
location = i / 8;
bit = 7 - (i % 8);
switch (state) {
case HG_CHUNK_FREE:
h2o->bitmaps[location] &= ~(1 << bit);
+ if (i == start)
+ used_size -= size;
break;
case HG_CHUNK_USED:
h2o->bitmaps[location] |= (1 << bit);
+ if (i == start)
+ used_size += size;
break;
default:
break;
}
}
- G_LOCK (visualizer);
+ g_hash_table_insert(visual->pool2used_size, g_strdup(name), GSIZE_TO_POINTER (used_size));
+
visual->need_update = TRUE;
_hg_memory_visualizer_add_idle(visual);
G_UNLOCK (visualizer);
@@ -582,12 +753,25 @@ hg_memory_visualizer_change_pool(HgMemoryVisualizer *visual,
if (g_slist_find(visual->pool_name_list, name) != NULL) {
visual->current_pool_name = name;
visual->current_h2o = g_hash_table_lookup(visual->pool2array, name);
- G_LOCK (visualizer);
- visual->need_update = TRUE;
- _hg_memory_visualizer_add_idle(visual);
- G_UNLOCK (visualizer);
+ _hg_memory_visualizer_redraw_in_pixmap(visual);
} else {
/* send a signal to update the out of date list */
g_signal_emit(visual, signals[POOL_UPDATED], 0, visual->pool_name_list);
}
}
+
+gsize
+hg_memory_visualizer_get_used_size(HgMemoryVisualizer *visual,
+ const gchar *name)
+{
+ g_return_val_if_fail (HG_IS_MEMORY_VISUALIZER (visual), 0);
+ g_return_val_if_fail (name != NULL, 0);
+
+ return GPOINTER_TO_SIZE (g_hash_table_lookup(visual->pool2used_size, name));
+}
+
+const gchar *
+hg_memory_visualizer_get_current_pool_name(HgMemoryVisualizer *visual)
+{
+ return visual->current_pool_name;
+}
diff --git a/src/visualizer.h b/src/visualizer.h
index 1798f4c..10acb70 100644
--- a/src/visualizer.h
+++ b/src/visualizer.h
@@ -46,24 +46,27 @@ enum _HgMemoryChunkState {
};
-GType hg_memory_visualizer_get_type (void) G_GNUC_CONST;
-GtkWidget *hg_memory_visualizer_new (void);
-void hg_memory_visualizer_set_max_size (HgMemoryVisualizer *visual,
- const gchar *name,
- gsize size);
-gsize hg_memory_visualizer_get_max_size (HgMemoryVisualizer *visual,
- const gchar *name);
-void hg_memory_visualizer_set_heap_state (HgMemoryVisualizer *visual,
- const gchar *name,
- HgHeap *heap);
-void hg_memory_visualizer_set_chunk_state(HgMemoryVisualizer *visual,
- const gchar *name,
- gint heap_id,
- gsize offset,
- gsize size,
- HgMemoryChunkState state);
-void hg_memory_visualizer_change_pool (HgMemoryVisualizer *visual,
- const gchar *name);
+GType hg_memory_visualizer_get_type (void) G_GNUC_CONST;
+GtkWidget *hg_memory_visualizer_new (void);
+void hg_memory_visualizer_set_max_size (HgMemoryVisualizer *visual,
+ const gchar *name,
+ gsize size);
+gsize hg_memory_visualizer_get_max_size (HgMemoryVisualizer *visual,
+ const gchar *name);
+void hg_memory_visualizer_set_heap_state (HgMemoryVisualizer *visual,
+ const gchar *name,
+ HgHeap *heap);
+void hg_memory_visualizer_set_chunk_state (HgMemoryVisualizer *visual,
+ const gchar *name,
+ gint heap_id,
+ gsize offset,
+ gsize size,
+ HgMemoryChunkState state);
+void hg_memory_visualizer_change_pool (HgMemoryVisualizer *visual,
+ const gchar *name);
+gsize hg_memory_visualizer_get_used_size (HgMemoryVisualizer *visual,
+ const gchar *name);
+const gchar *hg_memory_visualizer_get_current_pool_name(HgMemoryVisualizer *visual);
G_END_DECLS