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;
|
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);
|
||||||
|
}
|
||||||
|
@@ -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))
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user