[glib/gobject-performance: 10/12] Don't reuse on non-grow



commit 4d85ac7b3fde2a7ec6f62af3d7a5e4332162e11f
Author: Alexander Larsson <alexl redhat com>
Date:   Wed Sep 9 16:42:04 2009 +0200

    Don't reuse on non-grow

 gobject/gatomicarray.c |   27 ++++++++++++++++++---------
 1 files changed, 18 insertions(+), 9 deletions(-)
---
diff --git a/gobject/gatomicarray.c b/gobject/gatomicarray.c
index b464403..8368056 100644
--- a/gobject/gatomicarray.c
+++ b/gobject/gatomicarray.c
@@ -28,18 +28,19 @@ static GList *freelist;
 
 /* must hold array lock */
 static gpointer
-freelist_alloc (gsize size)
+freelist_alloc (gsize size, gboolean reuse)
 {
   GList *walk;
   gpointer mem;
 
-  for (walk = freelist; walk; walk = walk->next) {
-    mem = walk->data;
-    if (ATOMIC_ARRAY_DATA_SIZE (mem) == size) {
-      freelist = g_list_delete_link (freelist, walk);
-      return mem;
+  if (reuse)
+    for (walk = freelist; walk; walk = walk->next) {
+      mem = walk->data;
+      if (ATOMIC_ARRAY_DATA_SIZE (mem) == size) {
+	freelist = g_list_delete_link (freelist, walk);
+	return mem;
+      }
     }
-  }
 
   mem = g_slice_alloc (size + sizeof (gsize));
   mem += sizeof (gsize);
@@ -68,19 +69,27 @@ g_atomic_array_copy (GAtomicArray *array,
   guint8 *new, *old;
   gsize old_size, new_size;
 
+  /* We don't support shrinking arrays, as if
+     we then re-grow we may reuse an old pointer
+     value and confuse the transaction check. */
+  g_assert (additional_element_size >= 0);
+
   G_LOCK (array);
   old = g_atomic_pointer_get (&array->data);
   if (old)
     {
       old_size = ATOMIC_ARRAY_DATA_SIZE (old);
       new_size = old_size + additional_element_size;
-      new = freelist_alloc (new_size);
+      /* Don't reuse if copying to same size, as this may end
+	 up reusing the same pointer for the same array thus
+	 confusing the transaction check */
+      new = freelist_alloc (new_size, additional_element_size != 0);
       memcpy (new, old, old_size);
     }
   else if (additional_element_size != 0)
     {
       new_size = header_size + additional_element_size;
-      new = freelist_alloc (new_size);
+      new = freelist_alloc (new_size, TRUE);
     }
   else
     new = NULL;



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