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

@ -1,3 +1,53 @@
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

View File

@ -1,3 +1,53 @@
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

View File

@ -1,3 +1,53 @@
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

View File

@ -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;
}

View File

@ -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"

View File

@ -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

View File

@ -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__

View File

@ -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

View File

@ -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];
};

View File

@ -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

View File

@ -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 */
};
void g_list_push_allocator (gpointer dummy) { /* present for binary compat only */ }
void g_list_pop_allocator (void) { /* present for binary compat only */ }
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;
}
else
{
list = current_allocator->free_lists;
current_allocator->free_lists = list->next;
}
}
G_UNLOCK (current_allocator);
list->next = NULL;
list->prev = NULL;
return list;
}
#define _g_list_alloc0() g_slice_new0 (GList)
#define _g_list_free1(list) g_slice_free (GList, list)
GList*
g_list_alloc (void)
{
return _g_list_alloc ();
return _g_list_alloc0 ();
}
void
g_list_free (GList *list)
{
if (list)
{
GList *last_node = list;
#ifdef ENABLE_GC_FRIENDLY
while (last_node->next)
{
last_node->data = NULL;
last_node->prev = NULL;
last_node = last_node->next;
}
last_node->data = NULL;
last_node->prev = 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_list_free_1 (GList *list)
{
if (list)
{
list->data = NULL;
#ifdef ENABLE_GC_FRIENDLY
list->prev = NULL;
#endif /* ENABLE_GC_FRIENDLY */
G_LOCK (current_allocator);
list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
G_UNLOCK (current_allocator);
}
g_slice_free_chain (sizeof (GList), list, G_STRUCT_OFFSET (GList, next));
}
void
g_list_free_1 (GList *list)
{
_g_list_free_1 (list);
_g_list_free1 (list);
}
#else /* DISABLE_MEM_POOLS */
#define _g_list_alloc g_list_alloc
GList*
g_list_alloc (void)
{
GList *list;
list = g_new0 (GList, 1);
return list;
}
void
g_list_free (GList *list)
{
GList *last;
while (list)
{
last = list;
list = list->next;
g_free (last);
}
}
#define _g_list_free_1 g_list_free_1
void
g_list_free_1 (GList *list)
{
g_free (list);
}
#endif
GList*
g_list_append (GList *list,
gpointer data)
@ -243,7 +65,7 @@ g_list_append (GList *list,
GList *new_list;
GList *last;
new_list = _g_list_alloc ();
new_list = _g_list_alloc0 ();
new_list->data = data;
if (list)
@ -265,7 +87,7 @@ g_list_prepend (GList *list,
{
GList *new_list;
new_list = _g_list_alloc ();
new_list = _g_list_alloc0 ();
new_list->data = data;
if (list)
@ -299,7 +121,7 @@ g_list_insert (GList *list,
if (!tmp_list)
return g_list_append (list, data);
new_list = _g_list_alloc ();
new_list = _g_list_alloc0 ();
new_list->data = data;
if (tmp_list->prev)
@ -405,7 +227,7 @@ g_list_remove (GList *list,
if (list == tmp)
list = list->next;
_g_list_free_1 (tmp);
_g_list_free1 (tmp);
break;
}
@ -434,7 +256,7 @@ g_list_remove_all (GList *list,
if (next)
next->prev = tmp->prev;
_g_list_free_1 (tmp);
_g_list_free1 (tmp);
tmp = next;
}
}
@ -474,7 +296,7 @@ g_list_delete_link (GList *list,
GList *link)
{
list = _g_list_remove_link (list, link);
_g_list_free_1 (link);
_g_list_free1 (link);
return list;
}
@ -488,13 +310,13 @@ g_list_copy (GList *list)
{
GList *last;
new_list = _g_list_alloc ();
new_list = _g_list_alloc0 ();
new_list->data = list->data;
last = new_list;
list = list->next;
while (list)
{
last->next = _g_list_alloc ();
last->next = _g_list_alloc0 ();
last->next->prev = last;
last = last->next;
last->data = list->data;
@ -686,7 +508,7 @@ g_list_insert_sorted (GList *list,
if (!list)
{
new_list = _g_list_alloc ();
new_list = _g_list_alloc0 ();
new_list->data = data;
return new_list;
}
@ -699,7 +521,7 @@ g_list_insert_sorted (GList *list,
cmp = (*func) (data, tmp_list->data);
}
new_list = _g_list_alloc ();
new_list = _g_list_alloc0 ();
new_list->data = data;
if ((!tmp_list->next) && (cmp > 0))

View File

@ -42,11 +42,10 @@ struct _GList
/* Doubly linked lists
*/
void g_list_push_allocator (GAllocator *allocator);
void g_list_pop_allocator (void);
GList* g_list_alloc (void);
void g_list_free (GList *list);
void g_list_free_1 (GList *list);
#define g_list_free1 g_list_free_1
GList* g_list_append (GList *list,
gpointer data);
GList* g_list_prepend (GList *list,
@ -102,6 +101,10 @@ gpointer g_list_nth_data (GList *list,
#define g_list_previous(list) ((list) ? (((GList *)(list))->prev) : NULL)
#define g_list_next(list) ((list) ? (((GList *)(list))->next) : NULL)
#ifndef G_DISABLE_DEPRECATED
void g_list_push_allocator (gpointer allocator);
void g_list_pop_allocator (void);
#endif
G_END_DECLS
#endif /* __G_LIST_H__ */

View File

@ -125,8 +125,6 @@ struct _GMainContext
gint in_check_or_prepare;
GPollRec *poll_records;
GPollRec *poll_free_list;
GMemChunk *poll_chunk;
guint n_poll_records;
GPollFD *cached_poll_array;
guint cached_poll_array_size;
@ -190,9 +188,9 @@ struct _GChildWatchSource
struct _GPollRec
{
gint priority;
GPollFD *fd;
GPollRec *next;
GPollRec *next; /* chaining via second pointer member allows use of g_slice_free_chain() */
gint priority;
};
#ifdef G_THREADS_ENABLED
@ -597,25 +595,12 @@ g_main_context_ref (GMainContext *context)
return context;
}
/* If DISABLE_MEM_POOLS is defined, then freeing the
* mem chunk won't free the records, so we have to
* do it manually. The conditionalization here is
* an optimization; g_mem_chunk_free() is a no-op
* when DISABLE_MEM_POOLS is set.
*/
#ifdef DISABLE_MEM_POOLS
static void
static inline void
poll_rec_list_free (GMainContext *context,
GPollRec *list)
{
while (list)
{
GPollRec *tmp_rec = list;
list = list->next;
g_chunk_free (tmp_rec, context->poll_chunk);
}
g_slice_free_chain (sizeof (GPollRec), list, G_STRUCT_OFFSET (GPollRec, next));
}
#endif /* DISABLE_MEM_POOLS */
/**
* g_main_context_unref:
@ -653,14 +638,8 @@ g_main_context_unref (GMainContext *context)
g_ptr_array_free (context->pending_dispatches, TRUE);
g_free (context->cached_poll_array);
#ifdef DISABLE_MEM_POLLS
poll_rec_list_free (context, context->poll_records);
poll_rec_list_free (context, context->poll_free_list);
#endif /* DISABLE_MEM_POOLS */
if (context->poll_chunk)
g_mem_chunk_destroy (context->poll_chunk);
#ifdef G_THREADS_ENABLED
if (g_thread_supported())
{
@ -2951,18 +2930,8 @@ g_main_context_add_poll_unlocked (GMainContext *context,
gint priority,
GPollFD *fd)
{
GPollRec *lastrec, *pollrec, *newrec;
if (!context->poll_chunk)
context->poll_chunk = g_mem_chunk_create (GPollRec, 32, G_ALLOC_ONLY);
if (context->poll_free_list)
{
newrec = context->poll_free_list;
context->poll_free_list = newrec->next;
}
else
newrec = g_chunk_new (GPollRec, context->poll_chunk);
GPollRec *lastrec, *pollrec;
GPollRec *newrec = g_slice_new (GPollRec);
/* This file descriptor may be checked before we ever poll */
fd->revents = 0;
@ -3035,12 +3004,7 @@ g_main_context_remove_poll_unlocked (GMainContext *context,
else
context->poll_records = pollrec->next;
#ifdef ENABLE_GC_FRIENDLY
pollrec->fd = NULL;
#endif /* ENABLE_GC_FRIENDLY */
pollrec->next = context->poll_free_list;
context->poll_free_list = pollrec;
g_slice_free (GPollRec, pollrec);
context->n_poll_records--;
break;

View File

@ -602,8 +602,55 @@ GMemVTable *glib_mem_profiler_table = &profiler_table;
#endif /* !G_DISABLE_CHECKS */
/* --- memory slices --- */
typedef struct {
gpointer dummy, next;
} MemSlice;
gpointer
g_slice_alloc (guint block_size)
{
return g_malloc (block_size);
}
gpointer
g_slice_alloc0 (guint block_size)
{
return g_malloc0 (block_size);
}
void
g_slice_free1 (guint block_size,
gpointer mem_block)
{
if (mem_block)
g_free (mem_block);
}
void
g_slice_free_chain (guint block_size,
gpointer mem_chain,
guint next_offset)
{
MemSlice *slice = mem_chain;
g_return_if_fail (next_offset == G_STRUCT_OFFSET (MemSlice, next));
g_return_if_fail (block_size >= sizeof (MemSlice));
while (slice)
{
MemSlice *current = slice;
slice = slice->next;
g_slice_free1 (block_size, current);
}
}
/* --- MemChunks --- */
#ifndef G_ALLOC_AND_FREE
typedef struct _GAllocator GAllocator;
typedef struct _GMemChunk GMemChunk;
#define G_ALLOC_ONLY 1
#define G_ALLOC_AND_FREE 2
#endif
typedef struct _GFreeAtom GFreeAtom;
typedef struct _GMemArea GMemArea;
@ -1219,50 +1266,28 @@ void g_blow_chunks (void) {}
#endif /* DISABLE_MEM_POOLS */
/* generic allocators
*/
struct _GAllocator /* from gmem.c */
{
gchar *name;
guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
gpointer dummy; /* implementation specific */
};
GAllocator*
g_allocator_new (const gchar *name,
guint n_preallocs)
{
GAllocator *allocator;
g_return_val_if_fail (name != NULL, NULL);
allocator = g_new0 (GAllocator, 1);
allocator->name = g_strdup (name);
allocator->n_preallocs = CLAMP (n_preallocs, 1, 65535);
allocator->is_unused = TRUE;
allocator->type = 0;
allocator->last = NULL;
allocator->mem_chunk = NULL;
allocator->dummy = NULL;
return allocator;
static const struct _GAllocator {
gchar *name;
guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
gpointer free_list;
} dummy = {
"GAllocator is deprecated", 0, TRUE, 0, NULL, NULL, NULL,
};
/* some (broken) GAllocator uses depend on non-NULL allocators */
return (GAllocator*) &dummy;
}
void
g_allocator_free (GAllocator *allocator)
{
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
g_free (allocator->name);
if (allocator->mem_chunk)
g_mem_chunk_destroy (allocator->mem_chunk);
g_free (allocator);
}
void

View File

@ -31,8 +31,6 @@
G_BEGIN_DECLS
typedef struct _GAllocator GAllocator;
typedef struct _GMemChunk GMemChunk;
typedef struct _GMemVTable GMemVTable;
@ -98,9 +96,24 @@ gboolean g_mem_is_system_malloc (void);
GLIB_VAR GMemVTable *glib_mem_profiler_table;
void g_mem_profile (void);
/* Memchunk convenience functions
/* slices - fast allocation/release of small memory blocks
*/
gpointer g_slice_alloc (guint block_size);
gpointer g_slice_alloc0 (guint block_size);
void g_slice_free1 (guint block_size,
gpointer mem_block);
void g_slice_free_chain (guint block_size,
gpointer mem_chain,
guint next_offset);
#define g_slice_new(type) ((type*) g_slice_alloc (sizeof (type)))
#define g_slice_new0(type) ((type*) g_slice_alloc0 (sizeof (type)))
#define g_slice_free(type,mem) g_slice_free1 (sizeof (type), mem)
/* deprecated memchunks and allocators */
#if !defined G_DISABLE_DEPRECATED || 1
typedef struct _GAllocator GAllocator;
typedef struct _GMemChunk GMemChunk;
#define g_mem_chunk_create(type, pre_alloc, alloc_type) ( \
g_mem_chunk_new (#type " mem chunks (" #pre_alloc ")", \
sizeof (type), \
@ -116,30 +129,8 @@ void g_mem_profile (void);
#define g_chunk_free(mem, mem_chunk) G_STMT_START { \
g_mem_chunk_free ((mem_chunk), (mem)); \
} G_STMT_END
/* "g_mem_chunk_new" creates a new memory chunk.
* Memory chunks are used to allocate pieces of memory which are
* always the same size. Lists are a good example of such a data type.
* The memory chunk allocates and frees blocks of memory as needed.
* Just be sure to call "g_mem_chunk_free" and not "g_free" on data
* allocated in a mem chunk. ("g_free" will most likely cause a seg
* fault...somewhere).
*
* Oh yeah, GMemChunk is an opaque data type. (You don't really
* want to know what's going on inside do you?)
*/
/* ALLOC_ONLY MemChunks can only allocate memory. The free operation
* is interpreted as a no op. ALLOC_ONLY MemChunks save 4 bytes per
* atom. (They are also useful for lists which use MemChunk to allocate
* memory but are also part of the MemChunk implementation).
* ALLOC_AND_FREE MemChunks can allocate and free memory.
*/
#define G_ALLOC_ONLY 1
#define G_ALLOC_AND_FREE 2
GMemChunk* g_mem_chunk_new (const gchar *name,
gint atom_size,
gulong area_size,
@ -153,29 +144,14 @@ void g_mem_chunk_clean (GMemChunk *mem_chunk);
void g_mem_chunk_reset (GMemChunk *mem_chunk);
void g_mem_chunk_print (GMemChunk *mem_chunk);
void g_mem_chunk_info (void);
/* Ah yes...we have a "g_blow_chunks" function.
* "g_blow_chunks" simply compresses all the chunks. This operation
* consists of freeing every memory area that should be freed (but
* which we haven't gotten around to doing yet). And, no,
* "g_blow_chunks" doesn't follow the naming scheme, but it is a
* much better name than "g_mem_chunk_clean_all" or something
* similar.
*/
void g_blow_chunks (void);
/* Generic allocators
*/
GAllocator* g_allocator_new (const gchar *name,
guint n_preallocs);
void g_allocator_free (GAllocator *allocator);
/* internal */
#define G_ALLOCATOR_LIST (1)
#define G_ALLOCATOR_SLIST (2)
#define G_ALLOCATOR_NODE (3)
void g_blow_chunks (void);
GAllocator*g_allocator_new (const gchar *name,
guint n_preallocs);
void g_allocator_free (GAllocator *allocator);
#define G_ALLOCATOR_LIST (1)
#define G_ALLOCATOR_SLIST (2)
#define G_ALLOCATOR_NODE (3)
#endif /* G_DISABLE_DEPRECATED */
G_END_DECLS

View File

@ -36,170 +36,33 @@
#include "glib.h"
#include "galias.h"
#ifndef DISABLE_MEM_POOLS
/* node allocation
*/
struct _GAllocator /* from gmem.c */
{
gchar *name;
guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
GNode *free_nodes; /* implementation specific */
};
G_LOCK_DEFINE_STATIC (current_allocator);
static GAllocator *current_allocator = NULL;
/* HOLDS: current_allocator_lock */
static void
g_node_validate_allocator (GAllocator *allocator)
{
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
if (allocator->type != G_ALLOCATOR_NODE)
{
allocator->type = G_ALLOCATOR_NODE;
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 (GNode),
sizeof (GNode) * allocator->n_preallocs,
G_ALLOC_ONLY);
allocator->free_nodes = NULL;
}
allocator->is_unused = FALSE;
}
void
g_node_push_allocator (GAllocator *allocator)
{
G_LOCK (current_allocator);
g_node_validate_allocator (allocator);
allocator->last = current_allocator;
current_allocator = allocator;
G_UNLOCK (current_allocator);
}
void
g_node_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);
}
void g_node_push_allocator (gpointer dummy) { /* present for binary compat only */ }
void g_node_pop_allocator (void) { /* present for binary compat only */ }
#define g_node_alloc0() g_slice_new0 (GNode)
#define g_node_free(node) g_slice_free (GNode, node)
/* --- functions --- */
GNode*
g_node_new (gpointer data)
{
GNode *node;
G_LOCK (current_allocator);
if (!current_allocator)
{
GAllocator *allocator = g_allocator_new ("GLib default GNode allocator",
128);
g_node_validate_allocator (allocator);
allocator->last = NULL;
current_allocator = allocator;
}
if (!current_allocator->free_nodes)
node = g_chunk_new (GNode, current_allocator->mem_chunk);
else
{
node = current_allocator->free_nodes;
current_allocator->free_nodes = node->next;
}
G_UNLOCK (current_allocator);
GNode *node = g_node_alloc0();
node->data = data;
node->next = NULL;
node->prev = NULL;
node->parent = NULL;
node->children = NULL;
return node;
}
static void
g_nodes_free (GNode *node)
{
GNode *parent;
parent = node;
while (1)
while (node)
{
if (parent->children)
g_nodes_free (parent->children);
#ifdef ENABLE_GC_FRIENDLY
parent->data = NULL;
parent->prev = NULL;
parent->parent = NULL;
parent->children = NULL;
#endif /* ENABLE_GC_FRIENDLY */
if (parent->next)
parent = parent->next;
else
break;
}
G_LOCK (current_allocator);
parent->next = current_allocator->free_nodes;
current_allocator->free_nodes = node;
G_UNLOCK (current_allocator);
}
#else /* DISABLE_MEM_POOLS */
GNode*
g_node_new (gpointer data)
{
GNode *node;
node = g_new0 (GNode, 1);
node->data = data;
return node;
}
static void
g_nodes_free (GNode *root)
{
GNode *node, *next;
node = root;
while (node != NULL)
{
next = node->next;
g_nodes_free (node->children);
g_free (node);
GNode *next = node->next;
if (node->children)
g_nodes_free (node->children);
g_node_free (node);
node = next;
}
}
#endif
void
g_node_destroy (GNode *root)

View File

@ -76,8 +76,6 @@ struct _GNode
((GNode*) (node))->next == NULL)
#define G_NODE_IS_LEAF(node) (((GNode*) (node))->children == NULL)
void g_node_push_allocator (GAllocator *allocator);
void g_node_pop_allocator (void);
GNode* g_node_new (gpointer data);
void g_node_destroy (GNode *root);
void g_node_unlink (GNode *node);
@ -165,6 +163,10 @@ GNode* g_node_last_sibling (GNode *node);
#define g_node_first_child(node) ((node) ? \
((GNode*) (node))->children : NULL)
#ifndef G_DISABLE_DEPRECATED
void g_node_push_allocator (gpointer dummy);
void g_node_pop_allocator (void);
#endif
G_END_DECLS
#endif /* __G_NODE_H__ */

View File

@ -29,11 +29,6 @@
#include "glib.h"
#include "galias.h"
G_LOCK_DEFINE_STATIC (queue_memchunk);
static GMemChunk *queue_memchunk = NULL;
static GTrashStack *free_queue_nodes = NULL;
/**
* g_queue_new:
*
@ -44,27 +39,7 @@ static GTrashStack *free_queue_nodes = NULL;
GQueue*
g_queue_new (void)
{
GQueue *queue;
G_LOCK (queue_memchunk);
queue = g_trash_stack_pop (&free_queue_nodes);
if (!queue)
{
if (!queue_memchunk)
queue_memchunk = g_mem_chunk_new ("GLib GQueue chunk",
sizeof (GQueue),
sizeof (GQueue) * 128,
G_ALLOC_ONLY);
queue = g_chunk_new (GQueue, queue_memchunk);
}
G_UNLOCK (queue_memchunk);
queue->head = NULL;
queue->tail = NULL;
queue->length = 0;
return queue;
return g_slice_new0 (GQueue);
}
/**
@ -79,15 +54,7 @@ g_queue_free (GQueue *queue)
g_return_if_fail (queue != NULL);
g_list_free (queue->head);
#ifdef ENABLE_GC_FRIENDLY
queue->head = NULL;
queue->tail = NULL;
#endif /* ENABLE_GC_FRIENDLY */
G_LOCK (queue_memchunk);
g_trash_stack_push (&free_queue_nodes, queue);
G_UNLOCK (queue_memchunk);
g_slice_free (GQueue, queue);
}
/**

View File

@ -45,7 +45,6 @@ struct _GRelation
GHashTable *all_tuples;
GHashTable **hashed_tuple_tables;
GMemChunk *tuple_chunk;
gint count;
};
@ -109,16 +108,22 @@ g_relation_new (gint fields)
GRelation* rel = g_new0 (GRelation, 1);
rel->fields = fields;
rel->tuple_chunk = g_mem_chunk_new ("Relation Chunk",
fields * sizeof (gpointer),
fields * sizeof (gpointer) * 128,
G_ALLOC_AND_FREE);
rel->all_tuples = g_hash_table_new (tuple_hash (fields), tuple_equal (fields));
rel->hashed_tuple_tables = g_new0 (GHashTable*, fields);
return rel;
}
static void
relation_delete_value_tuple (gpointer tuple_key,
gpointer tuple_value,
gpointer user_data)
{
GRelation *relation = user_data;
gpointer *tuple = tuple_value;
g_slice_free1 (relation->fields * sizeof (gpointer), tuple);
}
static void
g_relation_free_array (gpointer key, gpointer value, gpointer user_data)
{
@ -132,9 +137,6 @@ g_relation_destroy (GRelation *relation)
if (relation)
{
g_hash_table_destroy (relation->all_tuples);
g_mem_chunk_destroy (relation->tuple_chunk);
for (i = 0; i < relation->fields; i += 1)
{
if (relation->hashed_tuple_tables[i])
@ -143,6 +145,9 @@ g_relation_destroy (GRelation *relation)
g_hash_table_destroy (relation->hashed_tuple_tables[i]);
}
}
g_hash_table_foreach (relation->all_tuples, relation_delete_value_tuple, relation);
g_hash_table_destroy (relation->all_tuples);
g_free (relation->hashed_tuple_tables);
g_free (relation);
@ -166,16 +171,16 @@ void
g_relation_insert (GRelation *relation,
...)
{
gpointer* tuple = g_chunk_new (gpointer, relation->tuple_chunk);
gpointer* tuple = g_slice_alloc (relation->fields * sizeof (gpointer));
va_list args;
gint i;
va_start(args, relation);
va_start (args, relation);
for (i = 0; i < relation->fields; i += 1)
tuple[i] = va_arg(args, gpointer);
tuple[i] = va_arg (args, gpointer);
va_end(args);
va_end (args);
g_hash_table_insert (relation->all_tuples, tuple, tuple);
@ -211,21 +216,21 @@ g_relation_delete_tuple (gpointer tuple_key,
gpointer user_data)
{
gpointer *tuple = (gpointer*) tuple_value;
GRelation *rel = (GRelation *) user_data;
GRelation *relation = (GRelation *) user_data;
gint j;
g_assert (tuple_key == tuple_value);
for (j = 0; j < rel->fields; j += 1)
for (j = 0; j < relation->fields; j += 1)
{
GHashTable *one_table = rel->hashed_tuple_tables[j];
GHashTable *one_table = relation->hashed_tuple_tables[j];
gpointer one_key;
GHashTable *per_key_table;
if (one_table == NULL)
continue;
if (j == rel->current_field)
if (j == relation->current_field)
/* can't delete from the table we're foreaching in */
continue;
@ -236,9 +241,10 @@ g_relation_delete_tuple (gpointer tuple_key,
g_hash_table_remove (per_key_table, tuple);
}
g_hash_table_remove (rel->all_tuples, tuple);
if (g_hash_table_remove (relation->all_tuples, tuple))
g_slice_free1 (relation->fields * sizeof (gpointer), tuple);
rel->count -= 1;
relation->count -= 1;
}
gint
@ -341,7 +347,7 @@ g_relation_count (GRelation *relation,
gboolean
g_relation_exists (GRelation *relation, ...)
{
gpointer* tuple = g_chunk_new (gpointer, relation->tuple_chunk);
gpointer *tuple = g_slice_alloc (relation->fields * sizeof (gpointer));
va_list args;
gint i;
gboolean result;
@ -355,7 +361,7 @@ g_relation_exists (GRelation *relation, ...)
result = g_hash_table_lookup (relation->all_tuples, tuple) != NULL;
g_mem_chunk_free (relation->tuple_chunk, tuple);
g_slice_free1 (relation->fields * sizeof (gpointer), tuple);
return result;
}

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))

View File

@ -41,11 +41,10 @@ struct _GSList
/* Singly linked lists
*/
void g_slist_push_allocator (GAllocator *allocator);
void g_slist_pop_allocator (void);
GSList* g_slist_alloc (void);
void g_slist_free (GSList *list);
void g_slist_free_1 (GSList *list);
#define g_slist_free1 g_slist_free_1
GSList* g_slist_append (GSList *list,
gpointer data);
GSList* g_slist_prepend (GSList *list,
@ -96,6 +95,10 @@ gpointer g_slist_nth_data (GSList *list,
guint n);
#define g_slist_next(slist) ((slist) ? (((GSList *)(slist))->next) : NULL)
#ifndef G_DISABLE_DEPRECATED
void g_slist_push_allocator (gpointer dummy);
void g_slist_pop_allocator (void);
#endif
G_END_DECLS
#endif /* __G_SLIST_H__ */

View File

@ -53,9 +53,6 @@ struct _GStringChunk
gsize default_size;
};
G_LOCK_DEFINE_STATIC (string_mem_chunk);
static GMemChunk *string_mem_chunk = NULL;
/* Hash Functions.
*/
@ -268,16 +265,7 @@ g_string_maybe_expand (GString* string,
GString*
g_string_sized_new (gsize dfl_size)
{
GString *string;
G_LOCK (string_mem_chunk);
if (!string_mem_chunk)
string_mem_chunk = g_mem_chunk_new ("string mem chunk",
sizeof (GString),
1024, G_ALLOC_AND_FREE);
string = g_chunk_new (GString, string_mem_chunk);
G_UNLOCK (string_mem_chunk);
GString *string = g_slice_new (GString);
string->allocated_len = 0;
string->len = 0;
@ -344,9 +332,7 @@ g_string_free (GString *string,
else
segment = string->str;
G_LOCK (string_mem_chunk);
g_mem_chunk_free (string_mem_chunk, string);
G_UNLOCK (string_mem_chunk);
g_slice_free (GString, string);
return segment;
}

View File

@ -76,6 +76,8 @@ struct _GRealThread
{
GThread thread;
gpointer private_data;
gpointer mem_private;
GRealThread *next;
gpointer retval;
GSystemThread system_thread;
};
@ -126,7 +128,7 @@ GThreadFunctions g_thread_functions_for_glib_use = {
static GMutex *g_once_mutex = NULL;
static GCond *g_once_cond = NULL;
static GPrivate *g_thread_specific_private = NULL;
static GSList *g_thread_all_threads = NULL;
static GRealThread *g_thread_all_threads = NULL;
static GSList *g_thread_free_indeces = NULL;
G_LOCK_DEFINE_STATIC (g_thread);
@ -465,7 +467,7 @@ void
g_static_private_free (GStaticPrivate *private_key)
{
guint index = private_key->index;
GSList *list;
GRealThread *thread;
if (!index)
return;
@ -473,12 +475,12 @@ g_static_private_free (GStaticPrivate *private_key)
private_key->index = 0;
G_LOCK (g_thread);
list = g_thread_all_threads;
while (list)
thread = g_thread_all_threads;
while (thread)
{
GRealThread *thread = list->data;
GArray *array = thread->private_data;
list = list->next;
thread = thread->next;
if (array && index <= array->len)
{
@ -529,8 +531,20 @@ g_thread_cleanup (gpointer data)
it is, the structure is freed in g_thread_join */
if (!thread->thread.joinable)
{
GRealThread *t, *p;
G_LOCK (g_thread);
g_thread_all_threads = g_slist_remove (g_thread_all_threads, data);
for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next)
{
if (t == thread)
{
if (p)
p->next = t->next;
else
g_thread_all_threads = t->next;
break;
}
}
G_UNLOCK (g_thread);
/* Just to make sure, this isn't used any more */
@ -581,7 +595,7 @@ g_thread_create_full (GThreadFunc func,
g_return_val_if_fail (priority >= G_THREAD_PRIORITY_LOW, NULL);
g_return_val_if_fail (priority <= G_THREAD_PRIORITY_URGENT, NULL);
result = g_new (GRealThread, 1);
result = g_new0 (GRealThread, 1);
result->thread.joinable = joinable;
result->thread.priority = priority;
@ -592,7 +606,8 @@ g_thread_create_full (GThreadFunc func,
G_THREAD_UF (thread_create, (g_thread_create_proxy, result,
stack_size, joinable, bound, priority,
&result->system_thread, &local_error));
g_thread_all_threads = g_slist_prepend (g_thread_all_threads, result);
result->next = g_thread_all_threads;
g_thread_all_threads = result;
G_UNLOCK (g_thread);
if (local_error)
@ -617,6 +632,7 @@ gpointer
g_thread_join (GThread* thread)
{
GRealThread* real = (GRealThread*) thread;
GRealThread *p, *t;
gpointer retval;
g_return_val_if_fail (thread, NULL);
@ -629,7 +645,17 @@ g_thread_join (GThread* thread)
retval = real->retval;
G_LOCK (g_thread);
g_thread_all_threads = g_slist_remove (g_thread_all_threads, thread);
for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next)
{
if (t == (GRealThread*) thread)
{
if (p)
p->next = t->next;
else
g_thread_all_threads = t->next;
break;
}
}
G_UNLOCK (g_thread);
/* Just to make sure, this isn't used any more */
@ -672,7 +698,7 @@ g_thread_self (void)
/* If no thread data is available, provide and set one. This
can happen for the main thread and for threads, that are not
created by GLib. */
thread = g_new (GRealThread, 1);
thread = g_new0 (GRealThread, 1);
thread->thread.joinable = FALSE; /* This is a save guess */
thread->thread.priority = G_THREAD_PRIORITY_NORMAL; /* This is
just a guess */
@ -686,7 +712,8 @@ g_thread_self (void)
g_private_set (g_thread_specific_private, thread);
G_LOCK (g_thread);
g_thread_all_threads = g_slist_prepend (g_thread_all_threads, thread);
thread->next = g_thread_all_threads;
g_thread_all_threads = thread;
G_UNLOCK (g_thread);
}
@ -841,5 +868,69 @@ g_static_rw_lock_free (GStaticRWLock* lock)
g_static_mutex_free (&lock->mutex);
}
/*
* Memory allocation can't use the regular GPrivate
* API, since that relies on GArray, which uses
* chunked memory.
*/
gpointer
_g_thread_mem_private_get (GThread *thread)
{
GRealThread *real_thread = (GRealThread*) thread;
return real_thread->mem_private;
}
void
_g_thread_mem_private_set (GThread *thread,
gpointer data)
{
GRealThread *real_thread = (GRealThread*) thread;
real_thread->mem_private = data;
}
/**
* g_thread_foreach
* @thread_func: function to call for all GThread structures
* @user_data: second argument to @thread_func
* Call @thread_func on all existing GThread structures. Note that
* threads may decide to exit while @thread_func is running, so
* without intimate knowledge about the lifetime of foreign threads,
* @thread_func shouldn't access the GThread* pointer passed in as
* first argument. However, @thread_func will not be called for threads
* which are known to have exited already.
* Due to thread lifetime checks, this function has an execution complexity
* which is quadratic in the number of existing threads.
*/
void
g_thread_foreach (GFunc thread_func,
gpointer user_data)
{
GSList *slist = NULL;
GRealThread *thread;
g_return_if_fail (thread_func != NULL);
/* snapshot the list of threads for iteration */
G_LOCK (g_thread);
for (thread = g_thread_all_threads; thread; thread = thread->next)
slist = g_slist_prepend (slist, thread);
G_UNLOCK (g_thread);
/* walk the list, skipping non-existant threads */
while (slist)
{
GSList *node = slist;
slist = node->next;
/* check whether the current thread still exists */
G_LOCK (g_thread);
for (thread = g_thread_all_threads; thread; thread = thread->next)
if (thread == node->data)
break;
G_UNLOCK (g_thread);
if (thread)
thread_func (thread, user_data);
g_slist_free_1 (node);
}
}
#define __G_THREAD_C__
#include "galiasdef.c"

View File

@ -289,6 +289,9 @@ gboolean g_static_rw_lock_writer_trylock (GStaticRWLock* lock);
void g_static_rw_lock_writer_unlock (GStaticRWLock* lock);
void g_static_rw_lock_free (GStaticRWLock* lock);
void g_thread_foreach (GFunc thread_func,
gpointer user_data);
typedef enum
{
G_ONCE_STATUS_NOTCALLED,
@ -367,6 +370,11 @@ extern void glib_dummy_decl (void);
# define G_TRYLOCK(name) (TRUE)
#endif /* !G_THREADS_ENABLED */
/* --- internal API --- */
gpointer _g_thread_mem_private_get (GThread *thread);
void _g_thread_mem_private_set (GThread *thread,
gpointer data);
G_END_DECLS
#endif /* __G_THREAD_H__ */

View File

@ -101,34 +101,11 @@ static GTreeNode* g_tree_node_rotate_right (GTreeNode *node);
static void g_tree_node_check (GTreeNode *node);
G_LOCK_DEFINE_STATIC (g_tree_global);
static GMemChunk *node_mem_chunk = NULL;
static GTreeNode *node_free_list = NULL;
static GTreeNode*
g_tree_node_new (gpointer key,
gpointer value)
{
GTreeNode *node;
G_LOCK (g_tree_global);
if (node_free_list)
{
node = node_free_list;
node_free_list = node->right;
}
else
{
if (!node_mem_chunk)
node_mem_chunk = g_mem_chunk_new ("GLib GTreeNode mem chunk",
sizeof (GTreeNode),
1024,
G_ALLOC_ONLY);
node = g_chunk_new (GTreeNode, node_mem_chunk);
}
G_UNLOCK (g_tree_global);
GTreeNode *node = g_slice_new (GTreeNode);
node->balance = 0;
node->left = NULL;
@ -162,10 +139,7 @@ g_tree_node_destroy (GTreeNode *node,
node->value = NULL;
#endif /* ENABLE_GC_FRIENDLY */
G_LOCK (g_tree_global);
node->right = node_free_list;
node_free_list = node;
G_UNLOCK (g_tree_global);
g_slice_free (GTreeNode, node);
}
}
@ -742,10 +716,7 @@ g_tree_node_remove (GTree *tree,
garbage->value = NULL;
#endif /* ENABLE_GC_FRIENDLY */
G_LOCK (g_tree_global);
garbage->right = node_free_list;
node_free_list = garbage;
G_UNLOCK (g_tree_global);
g_slice_free (GTreeNode, garbage);
*removed = TRUE;
}

View File

@ -1,3 +1,11 @@
Tue Nov 1 17:07:43 2005 Tim Janik <timj@imendio.com>
* gsignal.c: allocate signal handlers and handler match structures
via the new g_slice_*() API (get's rid of GList allocation hack).
* gtype.c: got rid of per-type memchunks. if GTypeInfo.n_preallocs
is > 0, objects are allocated via g_slice_*() instead of g_malloc().
2005-10-03 Matthias Clasen <mclasen@redhat.com>
* glib-mkenums.in: Really fix #314890.

View File

@ -42,7 +42,6 @@
/* pre allocation configurations
*/
#define MAX_STACK_VALUES (16)
#define HANDLER_PRE_ALLOC (48)
#define REPORT_BUG "please report occurrence circumstances to gtk-devel-list@gnome.org"
#ifdef G_ENABLE_DEBUG
@ -52,41 +51,6 @@ static volatile gpointer g_trap_instance_signals = NULL;
#endif /* G_ENABLE_DEBUG */
/* --- generic allocation --- */
/* we special case allocations generically by replacing
* these functions with more speed/memory aware variants
*/
#ifndef DISABLE_MEM_POOLS
static inline gpointer
g_generic_node_alloc (GTrashStack **trash_stack_p,
guint sizeof_node,
guint nodes_pre_alloc)
{
gpointer node = g_trash_stack_pop (trash_stack_p);
if (!node)
{
guint8 *block;
nodes_pre_alloc = MAX (nodes_pre_alloc, 1);
block = g_malloc (sizeof_node * nodes_pre_alloc);
while (--nodes_pre_alloc)
{
g_trash_stack_push (trash_stack_p, block);
block += sizeof_node;
}
node = block;
}
return node;
}
#define g_generic_node_free(trash_stack_p, node) g_trash_stack_push (trash_stack_p, node)
#else /* !DISABLE_MEM_POOLS */
#define g_generic_node_alloc(t,sizeof_node,p) g_malloc (sizeof_node)
#define g_generic_node_free(t,node) g_free (node)
#endif /* !DISABLE_MEM_POOLS */
/* --- typedefs --- */
typedef struct _SignalNode SignalNode;
typedef struct _SignalKey SignalKey;
@ -232,10 +196,7 @@ struct _HandlerMatch
{
Handler *handler;
HandlerMatch *next;
union {
guint signal_id;
gpointer dummy;
} d;
guint signal_id;
};
typedef struct
@ -434,10 +395,10 @@ handler_match_prepend (HandlerMatch *list,
* instead, we use GList* nodes, since they are exactly the size
* we need and are already cached. g_signal_init() asserts this.
*/
node = (HandlerMatch*) g_list_alloc ();
node = g_slice_new (HandlerMatch);
node->handler = handler;
node->next = list;
node->d.signal_id = signal_id;
node->signal_id = signal_id;
handler_ref (handler);
return node;
@ -448,8 +409,8 @@ handler_match_free1_R (HandlerMatch *node,
{
HandlerMatch *next = node->next;
handler_unref_R (node->d.signal_id, instance, node->handler);
g_list_free_1 ((GList*) node);
handler_unref_R (node->signal_id, instance, node->handler);
g_slice_free (HandlerMatch, node);
return next;
}
@ -541,9 +502,7 @@ handlers_find (gpointer instance,
static inline Handler*
handler_new (gboolean after)
{
Handler *handler = g_generic_node_alloc (&g_handler_ts,
sizeof (Handler),
HANDLER_PRE_ALLOC);
Handler *handler = g_slice_new (Handler);
#ifndef G_DISABLE_CHECKS
if (g_handler_sequential_number < 1)
g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG);
@ -624,7 +583,7 @@ handler_unref_R (guint signal_id,
SIGNAL_UNLOCK ();
g_closure_unref (handler->closure);
SIGNAL_LOCK ();
g_generic_node_free (&g_handler_ts, handler);
g_slice_free (Handler, handler);
}
}

View File

@ -278,7 +278,6 @@ struct _InstanceData
guint16 private_size;
guint16 n_preallocs;
GInstanceInitFunc instance_init;
GMemChunk *mem_chunk;
};
union _TypeData
{
@ -976,7 +975,6 @@ type_data_make_W (TypeNode *node,
data->instance.n_preallocs = MIN (info->n_preallocs, 1024);
#endif /* !DISABLE_MEM_POOLS */
data->instance.instance_init = info->instance_init;
data->instance.mem_chunk = NULL;
}
else if (node->is_classed) /* only classed */
{
@ -1526,8 +1524,7 @@ g_type_create_instance (GType type)
TypeNode *node;
GTypeInstance *instance;
GTypeClass *class;
guint i;
gsize total_instance_size;
guint i, total_size;
node = lookup_type_node_I (type);
if (!node || !node->is_instantiatable)
@ -1545,35 +1542,12 @@ g_type_create_instance (GType type)
}
class = g_type_class_ref (type);
total_size = type_total_instance_size_I (node);
total_instance_size = type_total_instance_size_I (node);
if (node->data->instance.n_preallocs)
{
G_WRITE_LOCK (&type_rw_lock);
if (!node->data->instance.mem_chunk)
{
/* If there isn't private data, the compiler will have already
* added the necessary padding, but in the private data case, we
* have to pad ourselves to ensure proper alignment of all the
* atoms in the slab.
*/
gsize atom_size = total_instance_size;
if (node->data->instance.private_size)
atom_size = ALIGN_STRUCT (atom_size);
node->data->instance.mem_chunk = g_mem_chunk_new (NODE_NAME (node),
atom_size,
(atom_size *
node->data->instance.n_preallocs),
G_ALLOC_AND_FREE);
}
instance = g_chunk_new0 (GTypeInstance, node->data->instance.mem_chunk);
G_WRITE_UNLOCK (&type_rw_lock);
}
instance = g_slice_alloc0 (total_size);
else
instance = g_malloc0 (total_instance_size); /* fine without read lock */
instance = g_malloc0 (total_size);
if (node->data->instance.private_size)
instance_real_class_set (instance, class);
@ -1624,17 +1598,13 @@ g_type_free_instance (GTypeInstance *instance)
instance->g_class = NULL;
#ifdef G_ENABLE_DEBUG
memset (instance, 0xaa, type_total_instance_size_I (node)); /* debugging hack */
#endif
memset (instance, 0xaa, type_total_instance_size_I (node));
#endif
if (node->data->instance.n_preallocs)
{
G_WRITE_LOCK (&type_rw_lock);
g_chunk_free (instance, node->data->instance.mem_chunk);
G_WRITE_UNLOCK (&type_rw_lock);
}
g_slice_free1 (type_total_instance_size_I (node), instance);
else
g_free (instance);
g_type_class_unref (class);
}
@ -2045,10 +2015,9 @@ type_data_last_unref_Wm (GType type,
node->data->common.ref_count = 0;
if (node->is_instantiatable && node->data->instance.mem_chunk)
if (node->is_instantiatable)
{
g_mem_chunk_destroy (node->data->instance.mem_chunk);
node->data->instance.mem_chunk = NULL;
/* destroy node->data->instance.mem_chunk */
}
tdata = node->data;