Improving scalability in glib



hi,

I've reported bugs 116805 and 144968 to gnome bugzilla about glib
scalability problems. I've also added a patch to the latter bugreport
which seems to help performance a lot.

As the patch I sent there only addresses a GString related problem I was
thinking about generalizing the solution a bit and address the same
issue in GArray, GQueue, GTree and so on.

For this purpose I've changed GMemChunks slightly, can you please
comment on it whether it would be worth completing?

I've added a G_ALLOC_AND_TRASH type code in addition to the G_ALLOC_ONLY
and G_ALLOC_AND_FREE types. This one actually uses a GTrashStack to keep
track of already freed chunks, so users of GMemChunks do not need to
implement it separately. I've also modified GString to show how it would
look like. Of course the subsystems which implement similar free lists
could be modified to remove the specific list and use G_ALLOC_AND_TRASH
instead.

And now the patch (against today's CVS):

Index: glib/gmem.c
===================================================================
RCS file: /cvs/gnome/glib/glib/gmem.c,v
retrieving revision 1.43
diff -u -r1.43 gmem.c
--- a/glib/gmem.c	21 Dec 2003 21:51:39 -0000	1.43
+++ b/glib/gmem.c	25 Jun 2004 15:48:22 -0000
@@ -36,6 +36,7 @@
 
 #include "glib.h"
 #include "gthreadinit.h"
+#include "gutils.h"
 
 /* notes on macros:
  * having DISABLE_MEM_POOLS defined, disables mem_chunks alltogether,
their
@@ -630,6 +631,7 @@
   GTree *mem_tree;           /* tree of mem areas sorted by memory
address */
   GMemChunk *next;           /* pointer to the next chunk */
   GMemChunk *prev;           /* pointer to the previous chunk */
+  GTrashStack *trash;        /* trash stack where freed items are
pushed */
 };
 

@@ -745,6 +747,10 @@
 
   g_return_val_if_fail (mem_chunk != NULL, NULL);
   
+  if (mem_chunk->type == G_ALLOC_AND_TRASH &&
+      (mem = g_stack_trash_pop(mem_chunk->trash)))
+    goto outa_here;
+  
   while (mem_chunk->free_atoms)
     {
       /* Get the first piece of memory on the "free_atoms" list.
@@ -923,6 +929,10 @@
 	  mem_chunk->num_marked_areas += 1;
 	}
     }
+  else if (mem_chunk->type == G_ALLOC_AND_TRASH)
+    {
+      g_stack_trash_push(&mem_chunk->trash, mem);
+    }
 
   LEAVE_MEM_CHUNK_ROUTINE ();
 }
Index: glib/gmem.h
===================================================================
RCS file: /cvs/gnome/glib/glib/gmem.h,v
retrieving revision 1.9
diff -u -r1.9 gmem.h
--- a/glib/gmem.h	6 Feb 2003 19:57:14 -0000	1.9
+++ b/glib/gmem.h	25 Jun 2004 15:48:22 -0000
@@ -131,6 +131,7 @@
 
 #define G_ALLOC_ONLY	  1
 #define G_ALLOC_AND_FREE  2
+#define G_ALLOC_AND_TRASH 3
 
 GMemChunk* g_mem_chunk_new     (const gchar *name,
 				gint         atom_size,
Index: glib/gstring.c
===================================================================
RCS file: /cvs/gnome/glib/glib/gstring.c,v
retrieving revision 1.41
diff -u -r1.41 gstring.c
--- a/glib/gstring.c	19 Feb 2004 17:42:00 -0000	1.41
+++ b/glib/gstring.c	25 Jun 2004 15:48:22 -0000
@@ -248,7 +248,7 @@
   if (!string_mem_chunk)
     string_mem_chunk = g_mem_chunk_new ("string mem chunk",
 					sizeof (GString),
-					1024, G_ALLOC_AND_FREE);
+					1024, G_ALLOC_AND_TRASH);
 
   string = g_chunk_new (GString, string_mem_chunk);
   G_UNLOCK (string_mem_chunk);



-- 
Bazsi
PGP info: KeyID 9AF8D0A9 Fingerprint CD27 CFB0 802C 0944 9CFD 804E C82C 8EB1





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]