mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-10-03 04:09:20 +02:00
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:
@@ -50,6 +50,9 @@ struct _FreeListNode {
|
||||
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
|
||||
* first item as the next pointer to chain them together.
|
||||
* 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 = ((char *) mem) + sizeof (gsize);
|
||||
G_ATOMIC_ARRAY_DATA_SIZE (mem) = size;
|
||||
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 */
|
||||
static void
|
||||
freelist_free (gpointer mem)
|
||||
@@ -166,3 +189,10 @@ _g_atomic_array_update (GAtomicArray *array,
|
||||
freelist_free (old);
|
||||
G_UNLOCK (array);
|
||||
}
|
||||
|
||||
void
|
||||
_g_atomic_array_free (GAtomicArray *array)
|
||||
{
|
||||
if (array->data != NULL)
|
||||
freelist_free (array->data);
|
||||
}
|
||||
|
@@ -35,11 +35,13 @@ struct _GAtomicArray {
|
||||
};
|
||||
|
||||
void _g_atomic_array_init (GAtomicArray *array);
|
||||
void _g_atomic_array_free (GAtomicArray *array);
|
||||
gpointer _g_atomic_array_copy (GAtomicArray *array,
|
||||
gsize header_size,
|
||||
gsize additional_element_size);
|
||||
void _g_atomic_array_update (GAtomicArray *array,
|
||||
gpointer new_data);
|
||||
void _g_atomic_array_cleanup(void);
|
||||
|
||||
#define G_ATOMIC_ARRAY_GET_LOCKED(_array, _type) ((_type *)((_array)->data))
|
||||
|
||||
|
Reference in New Issue
Block a user