[dia] New development-only plug-in: stress
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] New development-only plug-in: stress
- Date: Sat, 2 Apr 2011 16:00:41 +0000 (UTC)
commit 79161756e1a909d33bbab016570f011f133799ee
Author: Hans Breuer <hans breuer org>
Date: Sun Mar 27 22:46:58 2011 +0200
New development-only plug-in: stress
This should not be installed anywhere, it's development only!
The only implemented function is 'eating' memory, to test
Dia under low memory conditions.
BEWARE: consecutive calls try to eat 9/10 of the available
memory. This will finally lead to hard program exit when
the next call to g_malloc() fails.
It is still useful to reproduce bugs like bug 643285 without
swapping, because the memory is just 'eaten' from the address
space, not from real memory. Win32 only for the moment.
plug-ins/makefile.msc | 8 ++-
plug-ins/stress/stress-memory.c | 131 +++++++++++++++++++++++++++++++++++++++
plug-ins/stress/stress-memory.h | 7 ++
plug-ins/stress/stress.c | 93 +++++++++++++++++++++++++++
4 files changed, 238 insertions(+), 1 deletions(-)
---
diff --git a/plug-ins/makefile.msc b/plug-ins/makefile.msc
index 64a4cef..82fe3da 100644
--- a/plug-ins/makefile.msc
+++ b/plug-ins/makefile.msc
@@ -3,7 +3,7 @@
# dummy sissi
PLUGINS = cairo cgm dxf hpgl libart metapost pgf pixbuf \
postscript pstricks shape svg vdx wmf wpg xfig xslt \
- drs
+ drs stress
# The main target
all : sub-all
@@ -137,6 +137,12 @@ OBJECTS = \
shape-export.obj
!ENDIF
+!IFDEF OBJ_stress
+OBJECTS = \
+ stress.obj \
+ stress-memory.obj
+!ENDIF
+
!IFDEF OBJ_svg
OBJECTS = \
svg.obj \
diff --git a/plug-ins/stress/stress-memory.c b/plug-ins/stress/stress-memory.c
new file mode 100644
index 0000000..5d74573
--- /dev/null
+++ b/plug-ins/stress/stress-memory.c
@@ -0,0 +1,131 @@
+/*
+ * stress-memory.c -- functions to play around with virtual memory
+ *
+ * Copyright (C) 2011, Hans Breuer <hans breuer org>
+ *
+ * This program 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.
+ *
+ * This program 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.
+ */
+
+/* NOTHING Dia specific HERE */
+#include "stress-memory.h"
+
+#ifdef G_OS_WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+gboolean
+vmem_avail (guint64 *size)
+{
+ guint64 avail = 0;
+ gpointer p = NULL;
+#ifdef G_OS_WIN32
+ MEMORY_BASIC_INFORMATION mbi;
+
+ while (VirtualQuery (p, &mbi, sizeof(mbi))) {
+ if (MEM_FREE == mbi.State)
+ avail += mbi.RegionSize;
+ p = ((char*)mbi.BaseAddress + mbi.RegionSize);
+ }
+#else
+ return FALSE;
+#endif
+ if (size)
+ *size = avail;
+ return (avail > 0);
+}
+
+static GHashTable *virtual_reserved = NULL;
+
+gboolean
+vmem_reserve (guint64 size)
+{
+ if (!virtual_reserved)
+ virtual_reserved = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+#ifdef G_OS_WIN32
+ {
+ /* scan entire process for contiguous blocks of memory */
+ gpointer p = NULL;
+ gsize maxbs = 0, bs; /* maximum block size */
+ guint64 size_to_eat = size;
+ guint64 page_size;
+ MEMORY_BASIC_INFORMATION mbi;
+ SYSTEM_INFO si;
+
+ GetSystemInfo (&si);
+ page_size = si.dwPageSize;
+
+ while (VirtualQuery (p, &mbi, sizeof(mbi))) {
+ if (MEM_FREE == mbi.State)
+ if (mbi.RegionSize > maxbs)
+ maxbs = mbi.RegionSize;
+ p = ((char*)mbi.BaseAddress + mbi.RegionSize);
+ }
+ if (maxbs < page_size)
+ return TRUE;
+ bs = maxbs;
+ while (size_to_eat >= page_size) {
+ /* start with the largest free block */
+ if (size_to_eat > bs) { /* reserve but MEM_COMMIT */
+ p = VirtualAlloc(NULL, bs, MEM_RESERVE, PAGE_READWRITE);
+ if (p) {
+ g_hash_table_insert (virtual_reserved, p, (gpointer)bs);
+ size_to_eat -= bs;
+ } else {
+ /* reduce block size to request as a whole */
+ if (bs <= page_size)
+ break;
+ bs -= page_size;
+ }
+ } else {
+ /* find a convenient bs to start reserving */
+ while (size_to_eat < bs && bs > page_size)
+ bs = bs >> 1;
+ if (bs < page_size)
+ break;
+ }
+ /* the while loop is ignoring extra memory used for the hash */
+ }
+ /* done anything */
+ return (size_to_eat < size);
+ }
+#else
+ return FALSE;
+#endif
+}
+
+static void
+_release_one (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+#ifdef G_OS_WIN32
+ if (key)
+ VirtualFree(key, 0, MEM_RELEASE);
+#else
+ g_print ("release_one?");
+#endif
+}
+
+void
+vmem_release (void)
+{
+ if (virtual_reserved) {
+ g_hash_table_foreach (virtual_reserved, _release_one, NULL);
+ g_hash_table_destroy (virtual_reserved);
+ virtual_reserved = NULL;
+ }
+}
diff --git a/plug-ins/stress/stress-memory.h b/plug-ins/stress/stress-memory.h
new file mode 100644
index 0000000..bc37d19
--- /dev/null
+++ b/plug-ins/stress/stress-memory.h
@@ -0,0 +1,7 @@
+#include <glib.h>
+
+gboolean vmem_avail (guint64 *size);
+gboolean vmem_reserve (guint64 size);
+void vmem_release (void);
+
+
diff --git a/plug-ins/stress/stress.c b/plug-ins/stress/stress.c
new file mode 100644
index 0000000..f746a96
--- /dev/null
+++ b/plug-ins/stress/stress.c
@@ -0,0 +1,93 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * autolayout-register.c - registeration of auto-layout algoritms as plug-in
+ * Copyright (c) 2008 Hans Breuer <hans breuer org>
+ *
+ * This program 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.
+ *
+ * This program 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.
+ */
+#include <config.h>
+
+#include "intl.h"
+#include "message.h"
+#include "filter.h"
+#include "plug-ins.h"
+
+#include "stress-memory.h"
+
+static void
+stress_memory_callback (DiagramData *data,
+ const gchar *filename,
+ guint flags, /* further additions */
+ void *user_data)
+{
+ guint64 avail;
+
+ if (vmem_avail (&avail)) {
+ guint64 eat = (avail * 9) / 10;
+
+ if (vmem_reserve (eat)) {
+ guint64 still_avail;
+ vmem_avail (&still_avail);
+
+ message_warning ("%d MB of memory reserved,\n%d MB still available.\n",
+ (guint)((avail - still_avail)>>20),
+ (guint)(still_avail >> 20));
+ } else {
+ message_error ("Failed to reserve memory.");
+ }
+ } else {
+ message_error ("Failed to calculate available memory.");
+ }
+}
+
+static DiaCallbackFilter cb_stress_memory = {
+ "StressMemory",
+ N_("Stress memory"),
+ "/ToolboxMenu/Debug/StressMemory",
+ stress_memory_callback,
+ NULL
+};
+
+static gboolean
+_plugin_can_unload (PluginInfo *info)
+{
+ /* there is no filter_unregister_callback yet */
+ return TRUE;
+}
+
+static void
+_plugin_unload (PluginInfo *info)
+{
+ vmem_release ();
+}
+
+/* --- dia plug-in interface --- */
+
+DIA_PLUGIN_CHECK_INIT
+
+PluginInitResult
+dia_plugin_init(PluginInfo *info)
+{
+ if (!dia_plugin_info_init(info, "Stress",
+ _("Stress memory (development tool)"),
+ _plugin_can_unload,
+ _plugin_unload))
+ return DIA_PLUGIN_INIT_ERROR;
+
+ filter_register_callback (&cb_stress_memory);
+
+ return DIA_PLUGIN_INIT_OK;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]