Commit 0cba1b53 authored by Tim Janik's avatar Tim Janik Committed by Tim Janik

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.
parent 3a042a89
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.
2005-10-29 Matthias Clasen <mclasen@redhat.com>
* tests/convert-test.c: Add some tests for conversions between
......
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.
2005-10-29 Matthias Clasen <mclasen@redhat.com>
* tests/convert-test.c: Add some tests for conversions between
......
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.
2005-10-29 Matthias Clasen <mclasen@redhat.com>
* tests/convert-test.c: Add some tests for conversions between
......
......@@ -70,9 +70,6 @@ static gint g_nearest_pow (gint num) G_GNUC_CONST;
static void g_array_maybe_expand (GRealArray *array,
gint len);
static GMemChunk *array_mem_chunk = NULL;
G_LOCK_DEFINE_STATIC (array_mem_chunk);
GArray*
g_array_new (gboolean zero_terminated,
gboolean clear,
......@@ -86,16 +83,7 @@ GArray* g_array_sized_new (gboolean zero_terminated,
guint elt_size,
guint reserved_size)
{
GRealArray *array;
G_LOCK (array_mem_chunk);
if (!array_mem_chunk)
array_mem_chunk = g_mem_chunk_new ("array mem chunk",
sizeof (GRealArray),
1024, G_ALLOC_AND_FREE);
array = g_chunk_new (GRealArray, array_mem_chunk);
G_UNLOCK (array_mem_chunk);
GRealArray *array = g_slice_new (GRealArray);
array->data = NULL;
array->len = 0;
......@@ -129,9 +117,7 @@ g_array_free (GArray *array,
else
segment = array->data;
G_LOCK (array_mem_chunk);
g_mem_chunk_free (array_mem_chunk, array);
G_UNLOCK (array_mem_chunk);
g_slice_free1 (sizeof (GRealArray), array);
return segment;
}
......@@ -380,10 +366,6 @@ struct _GRealPtrArray
static void g_ptr_array_maybe_expand (GRealPtrArray *array,
gint len);
static GMemChunk *ptr_array_mem_chunk = NULL;
G_LOCK_DEFINE_STATIC (ptr_array_mem_chunk);
GPtrArray*
g_ptr_array_new (void)
{
......@@ -393,16 +375,7 @@ g_ptr_array_new (void)
GPtrArray*
g_ptr_array_sized_new (guint reserved_size)
{
GRealPtrArray *array;
G_LOCK (ptr_array_mem_chunk);
if (!ptr_array_mem_chunk)
ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
sizeof (GRealPtrArray),
1024, G_ALLOC_AND_FREE);
array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
G_UNLOCK (ptr_array_mem_chunk);
GRealPtrArray *array = g_slice_new (GRealPtrArray);
array->pdata = NULL;
array->len = 0;
......@@ -430,9 +403,7 @@ g_ptr_array_free (GPtrArray *array,
else
segment = array->pdata;
G_LOCK (ptr_array_mem_chunk);
g_mem_chunk_free (ptr_array_mem_chunk, array);
G_UNLOCK (ptr_array_mem_chunk);
g_slice_free1 (sizeof (GRealPtrArray), array);
return segment;
}
......
......@@ -64,13 +64,20 @@ struct _GCache
GHashTable *value_table;
};
static inline GCacheNode*
g_cache_node_new (gpointer value)
{
GCacheNode *node = g_slice_new (GCacheNode);
node->value = value;
node->ref_count = 1;
return node;
}
static GCacheNode* g_cache_node_new (gpointer value);
static void g_cache_node_destroy (GCacheNode *node);
static GMemChunk *node_mem_chunk = NULL;
G_LOCK_DEFINE_STATIC (node_mem_chunk);
static inline void
g_cache_node_destroy (GCacheNode *node)
{
g_slice_free (GCacheNode, node);
}
GCache*
g_cache_new (GCacheNewFunc value_new_func,
......@@ -91,7 +98,7 @@ g_cache_new (GCacheNewFunc value_new_func,
g_return_val_if_fail (hash_value_func != NULL, NULL);
g_return_val_if_fail (key_equal_func != NULL, NULL);
cache = g_new (GCache, 1);
cache = g_slice_new (GCache);
cache->value_new_func = value_new_func;
cache->value_destroy_func = value_destroy_func;
cache->key_dup_func = key_dup_func;
......@@ -109,7 +116,7 @@ g_cache_destroy (GCache *cache)
g_hash_table_destroy (cache->key_table);
g_hash_table_destroy (cache->value_table);
g_free (cache);
g_slice_free (GCache, cache);
}
gpointer
......@@ -186,33 +193,5 @@ g_cache_value_foreach (GCache *cache,
g_hash_table_foreach (cache->key_table, func, user_data);
}
static GCacheNode*
g_cache_node_new (gpointer value)
{
GCacheNode *node;
G_LOCK (node_mem_chunk);
if (!node_mem_chunk)
node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode),
1024, G_ALLOC_AND_FREE);
node = g_chunk_new (GCacheNode, node_mem_chunk);
G_UNLOCK (node_mem_chunk);
node->value = value;
node->ref_count = 1;
return node;
}
static void
g_cache_node_destroy (GCacheNode *node)
{
G_LOCK (node_mem_chunk);
g_mem_chunk_free (node_mem_chunk, node);
G_UNLOCK (node_mem_chunk);
}
#define __G_CACHE_C__
#include "galiasdef.c"
......@@ -41,9 +41,7 @@
/* --- defines --- */
#define G_QUARK_BLOCK_SIZE (512)
#define G_DATA_MEM_CHUNK_PREALLOC (128)
#define G_DATA_CACHE_MAX (512)
#define G_DATASET_MEM_CHUNK_PREALLOC (32)
/* datalist pointer modifications have to be done with the g_dataset_global mutex held */
#define G_DATALIST_GET_POINTER(datalist) \
......@@ -89,8 +87,6 @@ G_LOCK_DEFINE_STATIC (g_dataset_global);
static GHashTable *g_dataset_location_ht = NULL;
static GDataset *g_dataset_cached = NULL; /* should this be
threadspecific? */
static GMemChunk *g_dataset_mem_chunk = NULL;
static GMemChunk *g_data_mem_chunk = NULL;
static GData *g_data_cache = NULL;
static guint g_data_cache_length = 0;
......@@ -133,7 +129,7 @@ g_datalist_clear_i (GData **datalist)
g_data_cache_length++;
}
else
g_mem_chunk_free (g_data_mem_chunk, prev);
g_slice_free (GData, prev);
}
}
......@@ -181,7 +177,7 @@ g_dataset_destroy_internal (GDataset *dataset)
if (dataset == g_dataset_cached)
g_dataset_cached = NULL;
g_hash_table_remove (g_dataset_location_ht, dataset_location);
g_mem_chunk_free (g_dataset_mem_chunk, dataset);
g_slice_free (GDataset, dataset);
break;
}
......@@ -264,7 +260,7 @@ g_data_set_internal (GData **datalist,
g_data_cache_length++;
}
else
g_mem_chunk_free (g_data_mem_chunk, list);
g_slice_free (GData, list);
return ret_data;
}
......@@ -315,7 +311,7 @@ g_data_set_internal (GData **datalist,
g_data_cache_length--;
}
else
list = g_chunk_new (GData, g_data_mem_chunk);
list = g_slice_new (GData);
list->next = G_DATALIST_GET_POINTER (datalist);
list->id = key_id;
list->data = data;
......@@ -352,7 +348,7 @@ g_dataset_id_set_data_full (gconstpointer dataset_location,
dataset = g_dataset_lookup (dataset_location);
if (!dataset)
{
dataset = g_chunk_new (GDataset, g_dataset_mem_chunk);
dataset = g_slice_new (GDataset);
dataset->location = dataset_location;
g_datalist_init (&dataset->datalist);
g_hash_table_insert (g_dataset_location_ht,
......@@ -610,16 +606,6 @@ g_data_initialize (void)
g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL);
g_dataset_cached = NULL;
g_dataset_mem_chunk =
g_mem_chunk_new ("GDataset MemChunk",
sizeof (GDataset),
sizeof (GDataset) * G_DATASET_MEM_CHUNK_PREALLOC,
G_ALLOC_AND_FREE);
g_data_mem_chunk =
g_mem_chunk_new ("GData MemChunk",
sizeof (GData),
sizeof (GData) * G_DATA_MEM_CHUNK_PREALLOC,
G_ALLOC_AND_FREE);
}
GQuark
......
......@@ -84,13 +84,6 @@ static guint g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
gboolean notify);
#ifndef DISABLE_MEM_POOLS
G_LOCK_DEFINE_STATIC (g_hash_global);
static GMemChunk *node_mem_chunk = NULL;
static GHashNode *node_free_list = NULL;
#endif
/**
* g_hash_table_new:
* @hash_func: a function to create a hash value from a key.
......@@ -143,7 +136,7 @@ g_hash_table_new_full (GHashFunc hash_func,
GHashTable *hash_table;
guint i;
hash_table = g_new (GHashTable, 1);
hash_table = g_slice_new (GHashTable);
hash_table->size = HASH_TABLE_MIN_SIZE;
hash_table->nnodes = 0;
hash_table->hash_func = hash_func ? hash_func : g_direct_hash;
......@@ -181,7 +174,7 @@ g_hash_table_destroy (GHashTable *hash_table)
hash_table->value_destroy_func);
g_free (hash_table->nodes);
g_free (hash_table);
g_slice_free (GHashTable, hash_table);
}
static inline GHashNode**
......@@ -649,28 +642,7 @@ static GHashNode*
g_hash_node_new (gpointer key,
gpointer value)
{
GHashNode *hash_node;
#ifdef DISABLE_MEM_POOLS
hash_node = g_new (GHashNode, 1);
#else
G_LOCK (g_hash_global);
if (node_free_list)
{
hash_node = node_free_list;
node_free_list = node_free_list->next;
}
else
{
if (!node_mem_chunk)
node_mem_chunk = g_mem_chunk_new ("hash node mem chunk",
sizeof (GHashNode),
1024, G_ALLOC_ONLY);
hash_node = g_chunk_new (GHashNode, node_mem_chunk);
}
G_UNLOCK (g_hash_global);
#endif
GHashNode *hash_node = g_slice_new (GHashNode);
hash_node->key = key;
hash_node->value = value;
......@@ -694,14 +666,7 @@ g_hash_node_destroy (GHashNode *hash_node,
hash_node->value = NULL;
#endif /* ENABLE_GC_FRIENDLY */
#ifdef DISABLE_MEM_POOLS
g_free (hash_node);
#else
G_LOCK (g_hash_global);
hash_node->next = node_free_list;
node_free_list = hash_node;
G_UNLOCK (g_hash_global);
#endif
g_slice_free (GHashNode, hash_node);
}
static void
......@@ -709,55 +674,16 @@ g_hash_nodes_destroy (GHashNode *hash_node,
GFreeFunc key_destroy_func,
GFreeFunc value_destroy_func)
{
#ifdef DISABLE_MEM_POOLS
while (hash_node)
{
GHashNode *next = hash_node->next;
if (key_destroy_func)
key_destroy_func (hash_node->key);
if (value_destroy_func)
value_destroy_func (hash_node->value);
g_free (hash_node);
g_slice_free (GHashNode, hash_node);
hash_node = next;
}
#else
if (hash_node)
{
GHashNode *node = hash_node;
while (node->next)
{
if (key_destroy_func)
key_destroy_func (node->key);
if (value_destroy_func)
value_destroy_func (node->value);
#ifdef ENABLE_GC_FRIENDLY
node->key = NULL;
node->value = NULL;
#endif /* ENABLE_GC_FRIENDLY */
node = node->next;
}
if (key_destroy_func)
key_destroy_func (node->key);
if (value_destroy_func)
value_destroy_func (node->value);
#ifdef ENABLE_GC_FRIENDLY
node->key = NULL;
node->value = NULL;
#endif /* ENABLE_GC_FRIENDLY */
G_LOCK (g_hash_global);
node->next = node_free_list;
node_free_list = hash_node;
G_UNLOCK (g_hash_global);
}
#endif
}
#define __G_HASH_C__
......
......@@ -37,10 +37,6 @@
#include "galias.h"
/* --- defines --- */
#define G_HOOKS_PREALLOC (16)
/* --- functions --- */
static void
default_finalize_hook (GHookList *hook_list,
......@@ -61,16 +57,12 @@ g_hook_list_init (GHookList *hook_list,
{
g_return_if_fail (hook_list != NULL);
g_return_if_fail (hook_size >= sizeof (GHook));
g_return_if_fail (hook_size < 65536);
hook_list->seq_id = 1;
hook_list->hook_size = hook_size;
hook_list->is_setup = TRUE;
hook_list->hooks = NULL;
hook_list->hook_memchunk = g_mem_chunk_new ("GHook Memchunk",
hook_size,
hook_size * G_HOOKS_PREALLOC,
G_ALLOC_AND_FREE);
hook_list->dummy3 = NULL;
hook_list->finalize_hook = default_finalize_hook;
hook_list->dummy[0] = NULL;
hook_list->dummy[1] = NULL;
......@@ -90,8 +82,7 @@ g_hook_list_clear (GHookList *hook_list)
hook = hook_list->hooks;
if (!hook)
{
g_mem_chunk_destroy (hook_list->hook_memchunk);
hook_list->hook_memchunk = NULL;
/* destroy hook_list->hook_memchunk */
}
else
do
......@@ -105,8 +96,6 @@ g_hook_list_clear (GHookList *hook_list)
hook = tmp;
}
while (hook);
if (hook_list->hook_memchunk)
g_warning (G_STRLOC ": failed to clear hooklist, unconsolidated references on hooks left");
}
}
......@@ -118,7 +107,7 @@ g_hook_alloc (GHookList *hook_list)
g_return_val_if_fail (hook_list != NULL, NULL);
g_return_val_if_fail (hook_list->is_setup, NULL);
hook = g_chunk_new0 (GHook, hook_list->hook_memchunk);
hook = g_slice_alloc0 (hook_list->hook_size);
hook->data = NULL;
hook->next = NULL;
hook->prev = NULL;
......@@ -142,7 +131,7 @@ g_hook_free (GHookList *hook_list,
g_return_if_fail (!G_HOOK_IN_CALL (hook));
hook_list->finalize_hook (hook_list, hook);
g_chunk_free (hook, hook_list->hook_memchunk);
g_slice_free1 (hook_list->hook_size, hook);
}
void
......@@ -184,7 +173,6 @@ g_hook_unref (GHookList *hook_list,
GHook *hook)
{
g_return_if_fail (hook_list != NULL);
g_return_if_fail (hook_list->hook_memchunk != NULL);
g_return_if_fail (hook != NULL);
g_return_if_fail (hook->ref_count > 0);
......@@ -213,8 +201,7 @@ g_hook_unref (GHookList *hook_list,
if (!hook_list->hooks)
{
g_mem_chunk_destroy (hook_list->hook_memchunk);
hook_list->hook_memchunk = NULL;
/* destroy hook_list->hook_memchunk */
}
}
else
......
......@@ -64,7 +64,7 @@ struct _GHookList
guint hook_size : 16;
guint is_setup : 1;
GHook *hooks;
GMemChunk *hook_memchunk;
gpointer dummy3;
GHookFinalizeFunc finalize_hook;
gpointer dummy[2];
};
......
......@@ -565,6 +565,18 @@ g_markup_vprintf_escaped
#if IN_HEADER(__G_MEM_H__)
#if IN_FILE(__G_MEM_C__)
g_free
g_malloc G_GNUC_MALLOC
g_malloc0 G_GNUC_MALLOC
g_mem_is_system_malloc
g_mem_profile
g_mem_set_vtable
g_realloc
g_try_malloc G_GNUC_MALLOC
g_try_malloc0 G_GNUC_MALLOC
g_try_realloc
#ifndef G_DISABLE_DEPRECATED
g_allocator_free
g_allocator_new
g_mem_chunk_alloc
g_mem_chunk_alloc0
g_mem_chunk_clean
......@@ -574,18 +586,8 @@ g_mem_chunk_info
g_mem_chunk_new
g_mem_chunk_print
g_mem_chunk_reset
g_malloc G_GNUC_MALLOC
g_malloc0 G_GNUC_MALLOC
g_mem_is_system_malloc
g_mem_profile
g_mem_set_vtable
g_realloc
g_allocator_free
g_allocator_new
g_blow_chunks
g_try_malloc G_GNUC_MALLOC
g_try_malloc0 G_GNUC_MALLOC
g_try_realloc
#endif
#endif
#endif
......@@ -1031,6 +1033,7 @@ g_static_rw_lock_reader_unlock
g_static_rw_lock_writer_lock
g_static_rw_lock_writer_trylock
g_static_rw_lock_writer_unlock
g_thread_foreach
#endif
#endif
......
......@@ -34,208 +34,30 @@
#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;
GList *free_lists; /* implementation specific */
};
static GAllocator *current_allocator = NULL;
G_LOCK_DEFINE_STATIC (current_allocator);
/* HOLDS: current_allocator_lock */
static void
g_list_validate_allocator (GAllocator *allocator)
{
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
if (allocator->type != G_ALLOCATOR_LIST)
{
allocator->type = G_ALLOCATOR_LIST;
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 (GList),
sizeof (GList) * allocator->n_preallocs,
G_ALLOC_ONLY);
allocator->free_lists = NULL;
}
allocator->is_unused = FALSE;
}
void
g_list_push_allocator(GAllocator *allocator)
{
G_LOCK (current_allocator);
g_list_validate_allocator (allocator);
allocator->last = current_allocator;
current_allocator = allocator;
G_UNLOCK (current_allocator);
}
void
g_list_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 GList*
_g_list_alloc (void)
{
GList *list;
G_LOCK (current_allocator);
if (!current_allocator)
{
GAllocator *allocator = g_allocator_new ("GLib default GList allocator",
128);
g_list_validate_allocator (allocator);
allocator->last = NULL;
current_allocator = allocator;
}
if (!current_allocator->free_lists)
{
list = g_chunk_new (GList, 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;