gatomicarray: Support for cleaning up

Cleanup atomic array manually as very last thing
Otherwise we keep putting stuff in freelist during cleanup.

Initial work by: Dan Winship <danw@gnome.org>

https://bugzilla.gnome.org/show_bug.cgi?id=711778
This commit is contained in:
Stef Walter
2013-11-07 22:42:39 +01:00
parent 11dc3eedb5
commit b33fabd585
2 changed files with 33 additions and 1 deletions

View File

@@ -50,6 +50,9 @@ struct _FreeListNode {
FreeListNode *next; FreeListNode *next;
}; };
#define G_ATOMIC_ARRAY_REAL_SIZE_FROM(size) \
sizeof (gsize) + MAX (size, sizeof (FreeListNode))
/* This is really a list of array memory blocks, using the /* This is really a list of array memory blocks, using the
* first item as the next pointer to chain them together. * first item as the next pointer to chain them together.
* Protected by array lock */ * Protected by array lock */
@@ -75,13 +78,33 @@ freelist_alloc (gsize size, gboolean reuse)
} }
} }
real_size = sizeof (gsize) + MAX (size, sizeof (FreeListNode)); real_size = G_ATOMIC_ARRAY_REAL_SIZE_FROM (size);
mem = g_slice_alloc (real_size); mem = g_slice_alloc (real_size);
mem = ((char *) mem) + sizeof (gsize); mem = ((char *) mem) + sizeof (gsize);
G_ATOMIC_ARRAY_DATA_SIZE (mem) = size; G_ATOMIC_ARRAY_DATA_SIZE (mem) = size;
return mem; return mem;
} }
void
_g_atomic_array_cleanup (void)
{
FreeListNode *cur, *next;
cur = freelist;
freelist = NULL;
for (; cur; cur = next)
{
gsize size, real_size;
next = cur->next;
size = G_ATOMIC_ARRAY_DATA_SIZE (cur);
real_size = G_ATOMIC_ARRAY_REAL_SIZE_FROM (size);
g_slice_free1 (real_size, ((char *) cur) - sizeof (gsize));
}
}
/* must hold array lock */ /* must hold array lock */
static void static void
freelist_free (gpointer mem) freelist_free (gpointer mem)
@@ -166,3 +189,10 @@ _g_atomic_array_update (GAtomicArray *array,
freelist_free (old); freelist_free (old);
G_UNLOCK (array); G_UNLOCK (array);
} }
void
_g_atomic_array_free (GAtomicArray *array)
{
if (array->data != NULL)
freelist_free (array->data);
}

View File

@@ -35,11 +35,13 @@ struct _GAtomicArray {
}; };
void _g_atomic_array_init (GAtomicArray *array); void _g_atomic_array_init (GAtomicArray *array);
void _g_atomic_array_free (GAtomicArray *array);
gpointer _g_atomic_array_copy (GAtomicArray *array, gpointer _g_atomic_array_copy (GAtomicArray *array,
gsize header_size, gsize header_size,
gsize additional_element_size); gsize additional_element_size);
void _g_atomic_array_update (GAtomicArray *array, void _g_atomic_array_update (GAtomicArray *array,
gpointer new_data); gpointer new_data);
void _g_atomic_array_cleanup(void);
#define G_ATOMIC_ARRAY_GET_LOCKED(_array, _type) ((_type *)((_array)->data)) #define G_ATOMIC_ARRAY_GET_LOCKED(_array, _type) ((_type *)((_array)->data))