prepared deprecation of GMemChunk and GAllocator. added g_slice_*() API to

Tue Nov  1 16:24:20 2005  Tim Janik  <timj@imendio.com>

        * glib/gmem.[hc]: prepared deprecation of GMemChunk and GAllocator.
        added g_slice_*() API to allocate and cache small bits of memory.
        an actuall allocator implementation for g_slice_*() is still pending.

        * glib/gthread.[hc]: changes from a patch by Matthias Clasen.
        changed GRealThread list to use in-structure *next; fields instead
        of GSList, in order for thread iteration to not depenend on g_slice_*()
        indirectly.
        _g_thread_mem_private_get():
        _g_thread_mem_private_set(): added accessors for private memory,
        needed because the ordinary GPrivate implementation relies on GArray
        and GSList and therefore indirectly on working g_slice_*() allocations.

        * glib/gthread.[hc]:
        g_thread_foreach(): new public API function to loop over all existing threads.

        * glib/gdataset.c:
        * glib/gstring.c:
        * glib/gcache.c:
        * glib/garray.c:
        * glib/gqueue.c:
        * glib/gslist.c:
        * glib/glist.c:
        * glib/ghash.c:
        * glib/gtree.c:
        * glib/ghook.c:
        * glib/gmain.c:
        * glib/gnode.c:
        removed GAllocator and free list usages and accompanying locks.
        use g_slice_*() API to allocate and cache small bits of memory.

        * glib/ghook.h: removed GMemChunk field from public API.

        * glib/gslist.h:
        * glib/glist.h: deprecate allocator API, provide _free1() for consistency.

        * glib/gnode.h: deprecate allocator API.

        * glib/gmain.c: reordered GPollRec fields so g_slice_free_chain() can
        be used for poll rec lists.

        * glib/grel.c: removed mem chunk usage, and allocated tuples via g_slice_*().
        g_relation_destroy(): free all tuples from the all_tuples hash table,
        this effectively maintains the life time track keeping of tuples.
        g_relation_delete_tuple(): free tuples which are removed from the
        all_tuples hash table. this fixes a temporary leak that was present
        in the memchunk code until the destruction of the relation.
This commit is contained in:
Tim Janik
2005-11-01 18:10:31 +00:00
committed by Tim Janik
parent 3a042a8959
commit 0cba1b531d
28 changed files with 518 additions and 1063 deletions

View File

@@ -34,199 +34,29 @@
#include "galias.h"
#ifndef DISABLE_MEM_POOLS
struct _GAllocator /* from gmem.c */
{
gchar *name;
guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
GSList *free_lists; /* implementation specific */
};
void g_slist_push_allocator (gpointer dummy) { /* present for binary compat only */ }
void g_slist_pop_allocator (void) { /* present for binary compat only */ }
G_LOCK_DEFINE_STATIC (current_allocator);
static GAllocator *current_allocator = NULL;
/* HOLDS: current_allocator_lock */
static void
g_slist_validate_allocator (GAllocator *allocator)
{
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
if (allocator->type != G_ALLOCATOR_SLIST)
{
allocator->type = G_ALLOCATOR_SLIST;
if (allocator->mem_chunk)
{
g_mem_chunk_destroy (allocator->mem_chunk);
allocator->mem_chunk = NULL;
}
}
if (!allocator->mem_chunk)
{
allocator->mem_chunk = g_mem_chunk_new (allocator->name,
sizeof (GSList),
sizeof (GSList) * allocator->n_preallocs,
G_ALLOC_ONLY);
allocator->free_lists = NULL;
}
allocator->is_unused = FALSE;
}
void
g_slist_push_allocator (GAllocator *allocator)
{
G_LOCK (current_allocator);
g_slist_validate_allocator (allocator);
allocator->last = current_allocator;
current_allocator = allocator;
G_UNLOCK (current_allocator);
}
void
g_slist_pop_allocator (void)
{
G_LOCK (current_allocator);
if (current_allocator)
{
GAllocator *allocator;
allocator = current_allocator;
current_allocator = allocator->last;
allocator->last = NULL;
allocator->is_unused = TRUE;
}
G_UNLOCK (current_allocator);
}
static inline GSList*
_g_slist_alloc (void)
{
GSList *list;
G_LOCK (current_allocator);
if (!current_allocator)
{
GAllocator *allocator = g_allocator_new ("GLib default GSList allocator",
128);
g_slist_validate_allocator (allocator);
allocator->last = NULL;
current_allocator = allocator;
}
if (!current_allocator->free_lists)
{
list = g_chunk_new (GSList, current_allocator->mem_chunk);
list->data = NULL;
}
else
{
if (current_allocator->free_lists->data)
{
list = current_allocator->free_lists->data;
current_allocator->free_lists->data = list->next;
list->data = NULL;
}
else
{
list = current_allocator->free_lists;
current_allocator->free_lists = list->next;
}
}
G_UNLOCK (current_allocator);
list->next = NULL;
return list;
}
#define _g_slist_alloc0() g_slice_new0 (GSList)
#define _g_slist_free1(slist) g_slice_free (GSList, slist)
GSList*
g_slist_alloc (void)
{
return _g_slist_alloc ();
return _g_slist_alloc0 ();
}
void
g_slist_free (GSList *list)
g_slist_free (GSList *slist)
{
if (list)
{
GSList *last_node = list;
#ifdef ENABLE_GC_FRIENDLY
while (last_node->next)
{
last_node->data = NULL;
last_node = last_node->next;
}
last_node->data = NULL;
#else /* !ENABLE_GC_FRIENDLY */
list->data = list->next;
#endif /* ENABLE_GC_FRIENDLY */
G_LOCK (current_allocator);
last_node->next = current_allocator->free_lists;
current_allocator->free_lists = list;
G_UNLOCK (current_allocator);
}
}
static inline void
_g_slist_free_1 (GSList *list)
{
if (list)
{
list->data = NULL;
G_LOCK (current_allocator);
list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
G_UNLOCK (current_allocator);
}
g_slice_free_chain (sizeof (GSList), slist, G_STRUCT_OFFSET (GSList, next));
}
void
g_slist_free_1 (GSList *list)
g_slist_free_1 (GSList *slist)
{
_g_slist_free_1 (list);
_g_slist_free1 (slist);
}
#else /* DISABLE_MEM_POOLS */
#define _g_slist_alloc g_slist_alloc
GSList*
g_slist_alloc (void)
{
GSList *list;
list = g_new0 (GSList, 1);
return list;
}
void
g_slist_free (GSList *list)
{
GSList *last;
while (list)
{
last = list;
list = list->next;
g_free (last);
}
}
#define _g_slist_free_1 g_slist_free_1
void
g_slist_free_1 (GSList *list)
{
g_free (list);
}
#endif
GSList*
g_slist_append (GSList *list,
@@ -235,7 +65,7 @@ g_slist_append (GSList *list,
GSList *new_list;
GSList *last;
new_list = _g_slist_alloc ();
new_list = _g_slist_alloc0 ();
new_list->data = data;
if (list)
@@ -256,7 +86,7 @@ g_slist_prepend (GSList *list,
{
GSList *new_list;
new_list = _g_slist_alloc ();
new_list = _g_slist_alloc0 ();
new_list->data = data;
new_list->next = list;
@@ -277,7 +107,7 @@ g_slist_insert (GSList *list,
else if (position == 0)
return g_slist_prepend (list, data);
new_list = _g_slist_alloc ();
new_list = _g_slist_alloc0 ();
new_list->data = data;
if (!list)
@@ -458,7 +288,7 @@ g_slist_delete_link (GSList *list,
GSList *link)
{
list = _g_slist_remove_link (list, link);
_g_slist_free_1 (link);
_g_slist_free1 (link);
return list;
}
@@ -472,13 +302,13 @@ g_slist_copy (GSList *list)
{
GSList *last;
new_list = _g_slist_alloc ();
new_list = _g_slist_alloc0 ();
new_list->data = list->data;
last = new_list;
list = list->next;
while (list)
{
last->next = _g_slist_alloc ();
last->next = _g_slist_alloc0 ();
last = last->next;
last->data = list->data;
list = list->next;
@@ -647,7 +477,7 @@ g_slist_insert_sorted (GSList *list,
if (!list)
{
new_list = _g_slist_alloc ();
new_list = _g_slist_alloc0 ();
new_list->data = data;
return new_list;
}
@@ -661,7 +491,7 @@ g_slist_insert_sorted (GSList *list,
cmp = (*func) (data, tmp_list->data);
}
new_list = _g_slist_alloc ();
new_list = _g_slist_alloc0 ();
new_list->data = data;
if ((!tmp_list->next) && (cmp > 0))