prepared deprecation of GMemChunk and GAllocator. added g_slice_*() API to
authorTim Janik <timj@imendio.com>
Tue, 1 Nov 2005 18:10:31 +0000 (18:10 +0000)
committerTim Janik <timj@src.gnome.org>
Tue, 1 Nov 2005 18:10:31 +0000 (18:10 +0000)
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.

28 files changed:
ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-12
glib/garray.c
glib/gcache.c
glib/gdataset.c
glib/ghash.c
glib/ghook.c
glib/ghook.h
glib/glib.symbols
glib/glist.c
glib/glist.h
glib/gmain.c
glib/gmem.c
glib/gmem.h
glib/gnode.c
glib/gnode.h
glib/gqueue.c
glib/grel.c
glib/gslist.c
glib/gslist.h
glib/gstring.c
glib/gthread.c
glib/gthread.h
glib/gtree.c
gobject/ChangeLog
gobject/gsignal.c
gobject/gtype.c

index 0761d3d..1b3c98e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index 0761d3d..1b3c98e 100644 (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
index 0761d3d..1b3c98e 100644 (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
index 54ee05b..aca3b6a 100644 (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;
 }
index e3080c9..a5b0297 100644 (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"
index 37c3466..f0c46bc 100644 (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
index d3ae9ae..debb6c9 100644 (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__
index 88ff448..01ab78d 100644 (file)
 #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
index a552bfb..cb4f8e1 100644 (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];
 };
index 85a7b13..7ca791c 100644 (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
 
index ab94a3d..45799a5 100644 (file)
 #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;
-       }
-      else
-       {
-         list = current_allocator->free_lists;
-         current_allocator->free_lists = list->next;
-       }
-    }
-  G_UNLOCK (current_allocator);
-  list->next = NULL;
-  list->prev = NULL;
-  
-  return list;
-}
-
-GList*
-g_list_alloc (void)
-{
-  return _g_list_alloc ();
-}
-
-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;  
+void g_list_push_allocator (gpointer dummy) { /* present for binary compat only */ }
+void g_list_pop_allocator  (void)           { /* present for binary compat only */ }
 
-#ifdef ENABLE_GC_FRIENDLY
-      list->prev = NULL;  
-#endif /* ENABLE_GC_FRIENDLY */
+#define _g_list_alloc0()        g_slice_new0 (GList)
+#define _g_list_free1(list)     g_slice_free (GList, list)
 
-      G_LOCK (current_allocator);
-      list->next = current_allocator->free_lists;
-      current_allocator->free_lists = list;
-      G_UNLOCK (current_allocator);
-    }
-}
-
-void
-g_list_free_1 (GList *list)
-{
-  _g_list_free_1 (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;
+  return _g_list_alloc0 ();
 }
 
 void
 g_list_free (GList *list)
 {
-  GList *last;
-  
-  while (list)
-    {
-      last = list;
-      list = list->next;
-      g_free (last);
-    }
+  g_slice_free_chain (sizeof (GList), list, G_STRUCT_OFFSET (GList, next));
 }
 
-#define _g_list_free_1 g_list_free_1
 void
 g_list_free_1 (GList *list)
 {
-  g_free (list);
+  _g_list_free1 (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))
index 9434dde..fde99e5 100644 (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__ */
index b5021b3..b41438a 100644 (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;
index f2c6d20..44873f8 100644 (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
index 6966b28..6e1773e 100644 (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
 
index 572da5c..c9c5bcb 100644 (file)
 #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)
-    {
-      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)
+  while (node)
     {
-      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)
index 9da362a..a22c8fb 100644 (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__ */
index 2b149cf..f381db3 100644 (file)
 #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);
 }
 
 /**
index eeb9be4..814401b 100644 (file)
@@ -45,7 +45,6 @@ struct _GRelation
   
   GHashTable   *all_tuples;
   GHashTable  **hashed_tuple_tables;
-  GMemChunk    *tuple_chunk;
   
   gint count;
 };
@@ -109,10 +108,6 @@ 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);
   
@@ -120,6 +115,16 @@ g_relation_new (gint fields)
 }
 
 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)
 {
   g_hash_table_destroy ((GHashTable*) value);
@@ -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;
 }
index bdba1f3..6483f07 100644 (file)
 #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 */
-};
-
-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;
+void g_slist_push_allocator (gpointer dummy) { /* present for binary compat only */ }
+void g_slist_pop_allocator  (void)           { /* present for binary compat only */ }
 
-      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;
+#define _g_slist_alloc0()       g_slice_new0 (GSList)
+#define _g_slist_free1(slist)   g_slice_free (GSList, slist)
 
-  return list;
-}
-
-GSList*
-g_slist_alloc (void)
-{
-  return _g_slist_alloc ();
-}
-
-void
-g_slist_free (GSList *list)
-{
-  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);
-    }
-}
-
-void
-g_slist_free_1 (GSList *list)
-{
-  _g_slist_free_1 (list);
-}
-#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;
+  return _g_slist_alloc0 ();
 }
 
 void
-g_slist_free (GSList *list)
+g_slist_free (GSList *slist)
 {
-  GSList *last;
-  
-  while (list)
-    {
-      last = list;
-      list = list->next;
-      g_free (last);
-    }
+  g_slice_free_chain (sizeof (GSList), slist, G_STRUCT_OFFSET (GSList, next));
 }
 
-#define _g_slist_free_1 g_slist_free_1
 void
-g_slist_free_1 (GSList *list)
+g_slist_free_1 (GSList *slist)
 {
-  g_free (list);
+  _g_slist_free1 (slist);
 }
 
-#endif
-
 GSList*
 g_slist_append (GSList   *list,
                gpointer  data)
@@ -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))
index 72ce9d1..6df15dd 100644 (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__ */
index c0c0b6f..87ba2e2 100644 (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;
 }
index 85290db..d39faa2 100644 (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"
index 7471635..743981f 100644 (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__ */
index 1c81f3e..8411231 100644 (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;
    }
index 6fade6f..a35641a 100644 (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.
index 50eebdd..1da35bf 100644 (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);
     }
 }
 
index c67ed6d..3d312b2 100644 (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;