summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Janik <timj@gtk.org>1998-11-24 12:18:22 +0000
committerTim Janik <timj@src.gnome.org>1998-11-24 12:18:22 +0000
commit9c1692c2604bf147d2b08877d8cebb1f077658e0 (patch)
treefc6f6f3a2e46a638f65e448d71eff427716c2808
parenteabb208b306f159264ed14d0362b56b7749a70e2 (diff)
removed the GListAllocator type and its g_*_allocator_*() function
Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org> * glib.h: removed the GListAllocator type and its g_*_allocator_*() function variants (which weren't working anyways) in favour of a generic GAllocator type. new functions: g_allocator_new, g_allocator_free, g_slist_push_allocator, g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator, g_node_push_allocator and g_node_pop_allocator. * gstring.c: removed bogus slist allocator code. * gtree.c: maintain own list of free tree nodes and don't waste GSLists for that, removed bogus slist allocator code. * glist.c: use GAllocators for node allocation. * gslist.c: use GAllocators for node allocation. * gnode.c: use GAllocators for node allocation. * gdataset.c: cleanups wrt automatic initialization.
-rw-r--r--ChangeLog18
-rw-r--r--ChangeLog.pre-2-018
-rw-r--r--ChangeLog.pre-2-1018
-rw-r--r--ChangeLog.pre-2-1218
-rw-r--r--ChangeLog.pre-2-218
-rw-r--r--ChangeLog.pre-2-418
-rw-r--r--ChangeLog.pre-2-618
-rw-r--r--ChangeLog.pre-2-818
-rw-r--r--gdataset.c102
-rw-r--r--glib.h26
-rw-r--r--glib/gdataset.c102
-rw-r--r--glib/glib.h26
-rw-r--r--glib/glist.c136
-rw-r--r--glib/gmem.c46
-rw-r--r--glib/gnode.c113
-rw-r--r--glib/gslist.c111
-rw-r--r--glib/gstring.c7
-rw-r--r--glib/gtree.c101
-rw-r--r--glist.c136
-rw-r--r--gmem.c46
-rw-r--r--gnode.c113
-rw-r--r--gslist.c111
-rw-r--r--gstring.c7
-rw-r--r--gtree.c101
24 files changed, 918 insertions, 510 deletions
diff --git a/ChangeLog b/ChangeLog
index f13b2a632..4d0a13fc7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
+
+ * glib.h: removed the GListAllocator type and its g_*_allocator_*()
+ function variants (which weren't working anyways) in favour of a
+ generic GAllocator type. new functions:
+ g_allocator_new, g_allocator_free, g_slist_push_allocator,
+ g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
+ g_node_push_allocator and g_node_pop_allocator.
+
+ * gstring.c: removed bogus slist allocator code.
+ * gtree.c: maintain own list of free tree nodes and don't waste
+ GSLists for that, removed bogus slist allocator code.
+ * glist.c: use GAllocators for node allocation.
+ * gslist.c: use GAllocators for node allocation.
+ * gnode.c: use GAllocators for node allocation.
+
+ * gdataset.c: cleanups wrt automatic initialization.
+
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index f13b2a632..4d0a13fc7 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,21 @@
+Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
+
+ * glib.h: removed the GListAllocator type and its g_*_allocator_*()
+ function variants (which weren't working anyways) in favour of a
+ generic GAllocator type. new functions:
+ g_allocator_new, g_allocator_free, g_slist_push_allocator,
+ g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
+ g_node_push_allocator and g_node_pop_allocator.
+
+ * gstring.c: removed bogus slist allocator code.
+ * gtree.c: maintain own list of free tree nodes and don't waste
+ GSLists for that, removed bogus slist allocator code.
+ * glist.c: use GAllocators for node allocation.
+ * gslist.c: use GAllocators for node allocation.
+ * gnode.c: use GAllocators for node allocation.
+
+ * gdataset.c: cleanups wrt automatic initialization.
+
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index f13b2a632..4d0a13fc7 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,21 @@
+Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
+
+ * glib.h: removed the GListAllocator type and its g_*_allocator_*()
+ function variants (which weren't working anyways) in favour of a
+ generic GAllocator type. new functions:
+ g_allocator_new, g_allocator_free, g_slist_push_allocator,
+ g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
+ g_node_push_allocator and g_node_pop_allocator.
+
+ * gstring.c: removed bogus slist allocator code.
+ * gtree.c: maintain own list of free tree nodes and don't waste
+ GSLists for that, removed bogus slist allocator code.
+ * glist.c: use GAllocators for node allocation.
+ * gslist.c: use GAllocators for node allocation.
+ * gnode.c: use GAllocators for node allocation.
+
+ * gdataset.c: cleanups wrt automatic initialization.
+
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to
diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12
index f13b2a632..4d0a13fc7 100644
--- a/ChangeLog.pre-2-12
+++ b/ChangeLog.pre-2-12
@@ -1,3 +1,21 @@
+Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
+
+ * glib.h: removed the GListAllocator type and its g_*_allocator_*()
+ function variants (which weren't working anyways) in favour of a
+ generic GAllocator type. new functions:
+ g_allocator_new, g_allocator_free, g_slist_push_allocator,
+ g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
+ g_node_push_allocator and g_node_pop_allocator.
+
+ * gstring.c: removed bogus slist allocator code.
+ * gtree.c: maintain own list of free tree nodes and don't waste
+ GSLists for that, removed bogus slist allocator code.
+ * glist.c: use GAllocators for node allocation.
+ * gslist.c: use GAllocators for node allocation.
+ * gnode.c: use GAllocators for node allocation.
+
+ * gdataset.c: cleanups wrt automatic initialization.
+
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index f13b2a632..4d0a13fc7 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,21 @@
+Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
+
+ * glib.h: removed the GListAllocator type and its g_*_allocator_*()
+ function variants (which weren't working anyways) in favour of a
+ generic GAllocator type. new functions:
+ g_allocator_new, g_allocator_free, g_slist_push_allocator,
+ g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
+ g_node_push_allocator and g_node_pop_allocator.
+
+ * gstring.c: removed bogus slist allocator code.
+ * gtree.c: maintain own list of free tree nodes and don't waste
+ GSLists for that, removed bogus slist allocator code.
+ * glist.c: use GAllocators for node allocation.
+ * gslist.c: use GAllocators for node allocation.
+ * gnode.c: use GAllocators for node allocation.
+
+ * gdataset.c: cleanups wrt automatic initialization.
+
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index f13b2a632..4d0a13fc7 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,21 @@
+Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
+
+ * glib.h: removed the GListAllocator type and its g_*_allocator_*()
+ function variants (which weren't working anyways) in favour of a
+ generic GAllocator type. new functions:
+ g_allocator_new, g_allocator_free, g_slist_push_allocator,
+ g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
+ g_node_push_allocator and g_node_pop_allocator.
+
+ * gstring.c: removed bogus slist allocator code.
+ * gtree.c: maintain own list of free tree nodes and don't waste
+ GSLists for that, removed bogus slist allocator code.
+ * glist.c: use GAllocators for node allocation.
+ * gslist.c: use GAllocators for node allocation.
+ * gnode.c: use GAllocators for node allocation.
+
+ * gdataset.c: cleanups wrt automatic initialization.
+
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index f13b2a632..4d0a13fc7 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,21 @@
+Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
+
+ * glib.h: removed the GListAllocator type and its g_*_allocator_*()
+ function variants (which weren't working anyways) in favour of a
+ generic GAllocator type. new functions:
+ g_allocator_new, g_allocator_free, g_slist_push_allocator,
+ g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
+ g_node_push_allocator and g_node_pop_allocator.
+
+ * gstring.c: removed bogus slist allocator code.
+ * gtree.c: maintain own list of free tree nodes and don't waste
+ GSLists for that, removed bogus slist allocator code.
+ * glist.c: use GAllocators for node allocation.
+ * gslist.c: use GAllocators for node allocation.
+ * gnode.c: use GAllocators for node allocation.
+
+ * gdataset.c: cleanups wrt automatic initialization.
+
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index f13b2a632..4d0a13fc7 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,21 @@
+Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
+
+ * glib.h: removed the GListAllocator type and its g_*_allocator_*()
+ function variants (which weren't working anyways) in favour of a
+ generic GAllocator type. new functions:
+ g_allocator_new, g_allocator_free, g_slist_push_allocator,
+ g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
+ g_node_push_allocator and g_node_pop_allocator.
+
+ * gstring.c: removed bogus slist allocator code.
+ * gtree.c: maintain own list of free tree nodes and don't waste
+ GSLists for that, removed bogus slist allocator code.
+ * glist.c: use GAllocators for node allocation.
+ * gslist.c: use GAllocators for node allocation.
+ * gnode.c: use GAllocators for node allocation.
+
+ * gdataset.c: cleanups wrt automatic initialization.
+
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to
diff --git a/gdataset.c b/gdataset.c
index c62a8cdaa..7dafc2191 100644
--- a/gdataset.c
+++ b/gdataset.c
@@ -57,19 +57,19 @@ static inline void g_data_set_internal (GData **datalist,
GDestroyNotify destroy_func,
GDataset *dataset);
static void g_data_initialize (void);
-static inline GQuark g_quark_new (const gchar *string);
+static inline GQuark g_quark_new (gchar *string);
/* --- variables --- */
-static GHashTable *g_quark_ht = NULL;
-static gchar **g_quarks = NULL;
-static GQuark g_quark_seq_id = 0;
static GHashTable *g_dataset_location_ht = NULL;
static GDataset *g_dataset_cached = NULL;
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;
+static GHashTable *g_quark_ht = NULL;
+static gchar **g_quarks = NULL;
+static GQuark g_quark_seq_id = 0;
/* --- functions --- */
@@ -109,6 +109,9 @@ g_datalist_clear (GData **datalist)
{
g_return_if_fail (datalist != NULL);
+ if (!g_dataset_location_ht)
+ g_data_initialize ();
+
while (*datalist)
g_datalist_clear_i (datalist);
}
@@ -174,9 +177,6 @@ g_data_set_internal (GData **datalist,
{
register GData *list;
- if (!g_dataset_location_ht)
- g_data_initialize ();
-
list = *datalist;
if (!data)
{
@@ -201,7 +201,7 @@ g_data_set_internal (GData **datalist,
}
/* the GData struct *must* already be unlinked
- * when invoking the destroy function
+ * when invoking the destroy function.
* we use (data==NULL && destroy_func!=NULL) as
* a special hint combination to "steal"
* data without destroy notification
@@ -326,6 +326,9 @@ g_datalist_id_set_data_full (GData **datalist,
else
return;
}
+
+ if (!g_dataset_location_ht)
+ g_data_initialize ();
g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
}
@@ -352,7 +355,7 @@ g_datalist_id_remove_no_notify (GData **datalist,
{
g_return_if_fail (datalist != NULL);
- if (key_id)
+ if (key_id && g_dataset_location_ht)
g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
}
@@ -407,14 +410,17 @@ g_dataset_foreach (gconstpointer dataset_location,
g_return_if_fail (dataset_location != NULL);
g_return_if_fail (func != NULL);
-
- dataset = g_dataset_lookup (dataset_location);
- if (dataset)
+
+ if (g_dataset_location_ht)
{
- register GData *list;
-
- for (list = dataset->datalist; list; list = list->next)
- func (list->id, list->data, user_data);
+ dataset = g_dataset_lookup (dataset_location);
+ if (dataset)
+ {
+ register GData *list;
+
+ for (list = dataset->datalist; list; list = list->next)
+ func (list->id, list->data, user_data);
+ }
}
}
@@ -443,22 +449,20 @@ g_datalist_init (GData **datalist)
static void
g_data_initialize (void)
{
- if (!g_dataset_location_ht)
- {
- g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
- 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);
- }
+ g_return_if_fail (g_dataset_location_ht == NULL);
+
+ 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
@@ -479,10 +483,14 @@ g_quark_from_string (const gchar *string)
g_return_val_if_fail (string != NULL, 0);
- if (!g_quark_ht)
- g_data_initialize ();
+ if (g_quark_ht)
+ quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
+ else
+ {
+ g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
+ quark = 0;
+ }
- quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
if (!quark)
quark = g_quark_new (g_strdup (string));
@@ -496,12 +504,16 @@ g_quark_from_static_string (const gchar *string)
g_return_val_if_fail (string != NULL, 0);
- if (!g_quark_ht)
- g_data_initialize ();
-
- quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
+ if (g_quark_ht)
+ quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
+ else
+ {
+ g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
+ quark = 0;
+ }
+
if (!quark)
- quark = g_quark_new (string);
+ quark = g_quark_new ((gchar*) string);
return quark;
}
@@ -516,19 +528,17 @@ g_quark_to_string (GQuark quark)
}
static inline GQuark
-g_quark_new (const gchar *string)
+g_quark_new (gchar *string)
{
GQuark quark;
if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0)
- g_quarks = g_realloc (g_quarks,
- (g_quark_seq_id + G_QUARK_BLOCK_SIZE) * sizeof (gchar*));
-
+ g_quarks = g_renew (gchar*, g_quarks, g_quark_seq_id + G_QUARK_BLOCK_SIZE);
- g_quarks[g_quark_seq_id] = (gchar*) string;
+ g_quarks[g_quark_seq_id] = string;
g_quark_seq_id++;
quark = g_quark_seq_id;
- g_hash_table_insert (g_quark_ht, (gchar*) string, GUINT_TO_POINTER (quark));
+ g_hash_table_insert (g_quark_ht, string, GUINT_TO_POINTER (quark));
return quark;
}
diff --git a/glib.h b/glib.h
index 2e4982eb9..0442020f3 100644
--- a/glib.h
+++ b/glib.h
@@ -695,6 +695,7 @@ GUTILS_C_VAR const guint glib_binary_age;
/* Forward declarations of glib types.
*/
+typedef struct _GAllocator GAllocator;
typedef struct _GArray GArray;
typedef struct _GByteArray GByteArray;
typedef struct _GCache GCache;
@@ -705,7 +706,6 @@ typedef struct _GHashTable GHashTable;
typedef struct _GHook GHook;
typedef struct _GHookList GHookList;
typedef struct _GList GList;
-typedef struct _GListAllocator GListAllocator;
typedef struct _GMemChunk GMemChunk;
typedef struct _GNode GNode;
typedef struct _GPtrArray GPtrArray;
@@ -865,6 +865,8 @@ struct _GDebugKey
/* 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);
@@ -913,6 +915,8 @@ gpointer g_list_nth_data (GList *list,
/* 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);
@@ -957,14 +961,6 @@ gpointer g_slist_nth_data (GSList *list,
#define g_slist_next(slist) ((slist) ? (((GSList *)(slist))->next) : NULL)
-/* List Allocators
- */
-GListAllocator* g_list_allocator_new (void);
-void g_list_allocator_free (GListAllocator* allocator);
-GListAllocator* g_slist_set_allocator (GListAllocator* allocator);
-GListAllocator* g_list_set_allocator (GListAllocator* allocator);
-
-
/* Hash tables
*/
GHashTable* g_hash_table_new (GHashFunc hash_func,
@@ -1053,6 +1049,8 @@ 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);
@@ -1363,6 +1361,16 @@ void g_free (gpointer mem);
void g_mem_profile (void);
void g_mem_check (gpointer mem);
+/* Generic allocators
+ */
+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)
+
/* "g_mem_chunk_new" creates a new memory chunk.
* Memory chunks are used to allocate pieces of memory which are
diff --git a/glib/gdataset.c b/glib/gdataset.c
index c62a8cdaa..7dafc2191 100644
--- a/glib/gdataset.c
+++ b/glib/gdataset.c
@@ -57,19 +57,19 @@ static inline void g_data_set_internal (GData **datalist,
GDestroyNotify destroy_func,
GDataset *dataset);
static void g_data_initialize (void);
-static inline GQuark g_quark_new (const gchar *string);
+static inline GQuark g_quark_new (gchar *string);
/* --- variables --- */
-static GHashTable *g_quark_ht = NULL;
-static gchar **g_quarks = NULL;
-static GQuark g_quark_seq_id = 0;
static GHashTable *g_dataset_location_ht = NULL;
static GDataset *g_dataset_cached = NULL;
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;
+static GHashTable *g_quark_ht = NULL;
+static gchar **g_quarks = NULL;
+static GQuark g_quark_seq_id = 0;
/* --- functions --- */
@@ -109,6 +109,9 @@ g_datalist_clear (GData **datalist)
{
g_return_if_fail (datalist != NULL);
+ if (!g_dataset_location_ht)
+ g_data_initialize ();
+
while (*datalist)
g_datalist_clear_i (datalist);
}
@@ -174,9 +177,6 @@ g_data_set_internal (GData **datalist,
{
register GData *list;
- if (!g_dataset_location_ht)
- g_data_initialize ();
-
list = *datalist;
if (!data)
{
@@ -201,7 +201,7 @@ g_data_set_internal (GData **datalist,
}
/* the GData struct *must* already be unlinked
- * when invoking the destroy function
+ * when invoking the destroy function.
* we use (data==NULL && destroy_func!=NULL) as
* a special hint combination to "steal"
* data without destroy notification
@@ -326,6 +326,9 @@ g_datalist_id_set_data_full (GData **datalist,
else
return;
}
+
+ if (!g_dataset_location_ht)
+ g_data_initialize ();
g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
}
@@ -352,7 +355,7 @@ g_datalist_id_remove_no_notify (GData **datalist,
{
g_return_if_fail (datalist != NULL);
- if (key_id)
+ if (key_id && g_dataset_location_ht)
g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
}
@@ -407,14 +410,17 @@ g_dataset_foreach (gconstpointer dataset_location,
g_return_if_fail (dataset_location != NULL);
g_return_if_fail (func != NULL);
-
- dataset = g_dataset_lookup (dataset_location);
- if (dataset)
+
+ if (g_dataset_location_ht)
{
- register GData *list;
-
- for (list = dataset->datalist; list; list = list->next)
- func (list->id, list->data, user_data);
+ dataset = g_dataset_lookup (dataset_location);
+ if (dataset)
+ {
+ register GData *list;
+
+ for (list = dataset->datalist; list; list = list->next)
+ func (list->id, list->data, user_data);
+ }
}
}
@@ -443,22 +449,20 @@ g_datalist_init (GData **datalist)
static void
g_data_initialize (void)
{
- if (!g_dataset_location_ht)
- {
- g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
- 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);
- }
+ g_return_if_fail (g_dataset_location_ht == NULL);
+
+ 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
@@ -479,10 +483,14 @@ g_quark_from_string (const gchar *string)
g_return_val_if_fail (string != NULL, 0);
- if (!g_quark_ht)
- g_data_initialize ();
+ if (g_quark_ht)
+ quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
+ else
+ {
+ g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
+ quark = 0;
+ }
- quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
if (!quark)
quark = g_quark_new (g_strdup (string));
@@ -496,12 +504,16 @@ g_quark_from_static_string (const gchar *string)
g_return_val_if_fail (string != NULL, 0);
- if (!g_quark_ht)
- g_data_initialize ();
-
- quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
+ if (g_quark_ht)
+ quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
+ else
+ {
+ g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
+ quark = 0;
+ }
+
if (!quark)
- quark = g_quark_new (string);
+ quark = g_quark_new ((gchar*) string);
return quark;
}
@@ -516,19 +528,17 @@ g_quark_to_string (GQuark quark)
}
static inline GQuark
-g_quark_new (const gchar *string)
+g_quark_new (gchar *string)
{
GQuark quark;
if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0)
- g_quarks = g_realloc (g_quarks,
- (g_quark_seq_id + G_QUARK_BLOCK_SIZE) * sizeof (gchar*));
-
+ g_quarks = g_renew (gchar*, g_quarks, g_quark_seq_id + G_QUARK_BLOCK_SIZE);
- g_quarks[g_quark_seq_id] = (gchar*) string;
+ g_quarks[g_quark_seq_id] = string;
g_quark_seq_id++;
quark = g_quark_seq_id;
- g_hash_table_insert (g_quark_ht, (gchar*) string, GUINT_TO_POINTER (quark));
+ g_hash_table_insert (g_quark_ht, string, GUINT_TO_POINTER (quark));
return quark;
}
diff --git a/glib/glib.h b/glib/glib.h
index 2e4982eb9..0442020f3 100644
--- a/glib/glib.h
+++ b/glib/glib.h
@@ -695,6 +695,7 @@ GUTILS_C_VAR const guint glib_binary_age;
/* Forward declarations of glib types.
*/
+typedef struct _GAllocator GAllocator;
typedef struct _GArray GArray;
typedef struct _GByteArray GByteArray;
typedef struct _GCache GCache;
@@ -705,7 +706,6 @@ typedef struct _GHashTable GHashTable;
typedef struct _GHook GHook;
typedef struct _GHookList GHookList;
typedef struct _GList GList;
-typedef struct _GListAllocator GListAllocator;
typedef struct _GMemChunk GMemChunk;
typedef struct _GNode GNode;
typedef struct _GPtrArray GPtrArray;
@@ -865,6 +865,8 @@ struct _GDebugKey
/* 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);
@@ -913,6 +915,8 @@ gpointer g_list_nth_data (GList *list,
/* 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);
@@ -957,14 +961,6 @@ gpointer g_slist_nth_data (GSList *list,
#define g_slist_next(slist) ((slist) ? (((GSList *)(slist))->next) : NULL)
-/* List Allocators
- */
-GListAllocator* g_list_allocator_new (void);
-void g_list_allocator_free (GListAllocator* allocator);
-GListAllocator* g_slist_set_allocator (GListAllocator* allocator);
-GListAllocator* g_list_set_allocator (GListAllocator* allocator);
-
-
/* Hash tables
*/
GHashTable* g_hash_table_new (GHashFunc hash_func,
@@ -1053,6 +1049,8 @@ 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);
@@ -1363,6 +1361,16 @@ void g_free (gpointer mem);
void g_mem_profile (void);
void g_mem_check (gpointer mem);
+/* Generic allocators
+ */
+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)
+
/* "g_mem_chunk_new" creates a new memory chunk.
* Memory chunks are used to allocate pieces of memory which are
diff --git a/glib/glist.c b/glib/glist.c
index ee9ad695c..ab69826a2 100644
--- a/glib/glist.c
+++ b/glib/glist.c
@@ -19,99 +19,104 @@
#include "glib.h"
-typedef struct _GRealListAllocator GRealListAllocator;
-
-struct _GRealListAllocator
+struct _GAllocator /* from gmem.c */
{
- GMemChunk *list_mem_chunk;
- GList *free_list;
+ 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;
-static GRealListAllocator *default_allocator = NULL;
-static GRealListAllocator *current_allocator = NULL;
+void
+g_list_push_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;
+ }
+ }
-GListAllocator*
-g_list_allocator_new (void)
-{
- GRealListAllocator* allocator = g_new (GRealListAllocator, 1);
-
- allocator->list_mem_chunk = NULL;
- allocator->free_list = NULL;
-
- return (GListAllocator*) allocator;
-}
+ 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;
+ }
-void
-g_list_allocator_free (GListAllocator* fallocator)
-{
- GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
-
- if (allocator && allocator->list_mem_chunk)
- g_mem_chunk_destroy (allocator->list_mem_chunk);
- if (allocator)
- g_free (allocator);
+ allocator->is_unused = FALSE;
+ allocator->last = current_allocator;
+ current_allocator = allocator;
}
-GListAllocator*
-g_list_set_allocator (GListAllocator* fallocator)
+void
+g_list_pop_allocator (void)
{
- GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
- GRealListAllocator* old_allocator = current_allocator;
-
- if (allocator)
- current_allocator = allocator;
- else
+ if (current_allocator)
{
- if (!default_allocator)
- default_allocator = (GRealListAllocator*) g_list_allocator_new ();
- current_allocator = default_allocator;
+ GAllocator *allocator;
+
+ allocator = current_allocator;
+ current_allocator = allocator->last;
+ allocator->last = NULL;
+ allocator->is_unused = TRUE;
}
-
- if (!current_allocator->list_mem_chunk)
- current_allocator->list_mem_chunk = g_mem_chunk_new ("list mem chunk",
- sizeof (GList),
- 1024,
- G_ALLOC_ONLY);
-
- return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator);
}
-
GList*
g_list_alloc (void)
{
- GList *new_list;
-
- g_list_set_allocator (NULL);
- if (current_allocator->free_list)
+ GList *list;
+
+ if (!current_allocator)
+ g_list_push_allocator (g_allocator_new ("GLib default GList allocator", 1024));
+
+ if (!current_allocator->free_lists)
{
- new_list = current_allocator->free_list;
- current_allocator->free_list = current_allocator->free_list->next;
+ list = g_chunk_new (GList, current_allocator->mem_chunk);
+ list->data = NULL;
}
else
{
- new_list = g_chunk_new (GList, current_allocator->list_mem_chunk);
+ 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;
+ }
}
+ list->next = NULL;
+ list->prev = NULL;
- new_list->data = NULL;
- new_list->next = NULL;
- new_list->prev = NULL;
-
- return new_list;
+ return list;
}
void
g_list_free (GList *list)
{
- GList *last;
-
if (list)
{
- last = g_list_last (list);
- last->next = current_allocator->free_list;
- current_allocator->free_list = list;
+ list->data = list->next;
+ list->next = current_allocator->free_lists;
+ current_allocator->free_lists = list;
}
}
@@ -120,8 +125,9 @@ g_list_free_1 (GList *list)
{
if (list)
{
- list->next = current_allocator->free_list;
- current_allocator->free_list = list;
+ list->data = NULL;
+ list->next = current_allocator->free_lists;
+ current_allocator->free_lists = list;
}
}
diff --git a/glib/gmem.c b/glib/gmem.c
index cd7f47ea9..c29ee660f 100644
--- a/glib/gmem.c
+++ b/glib/gmem.c
@@ -894,3 +894,49 @@ g_mem_chunk_area_search (GMemArea *a,
}
return -1;
}
+
+/* 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;
+}
+
+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);
+}
diff --git a/glib/gnode.c b/glib/gnode.c
index dea428da6..9f6e544ba 100644
--- a/glib/gnode.c
+++ b/glib/gnode.c
@@ -21,33 +21,82 @@
*/
#include "glib.h"
+/* 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 */
+};
+
+static GAllocator *current_allocator = NULL;
+
+void
+g_node_push_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;
+ }
+ }
-#define KEEP_NODES (1024)
+ 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;
+ allocator->last = current_allocator;
+ current_allocator = allocator;
+}
+
+void
+g_node_pop_allocator (void)
+{
+ if (current_allocator)
+ {
+ GAllocator *allocator;
-/* --- variables --- */
-static GMemChunk *g_tree_node_chunk = NULL;
-static GNode *free_nodes = NULL;
-static guint n_free_nodes = 0;
+ allocator = current_allocator;
+ current_allocator = allocator->last;
+ allocator->last = NULL;
+ allocator->is_unused = TRUE;
+ }
+}
/* --- functions --- */
GNode*
g_node_new (gpointer data)
{
- register GNode *node;
-
- if (!g_tree_node_chunk)
- g_tree_node_chunk = g_mem_chunk_create (GNode, 1024, G_ALLOC_AND_FREE);
-
- if (n_free_nodes)
+ GNode *node;
+
+ if (!current_allocator)
+ g_node_push_allocator (g_allocator_new ("GLib default GNode allocator", 1024));
+
+ if (!current_allocator->free_nodes)
+ node = g_chunk_new (GNode, current_allocator->mem_chunk);
+ else
{
- node = free_nodes;
- free_nodes = free_nodes->next;
- n_free_nodes--;
+ node = current_allocator->free_nodes;
+ current_allocator->free_nodes = node->next;
}
- else
- node = g_chunk_new (GNode, g_tree_node_chunk);
node->data = data;
node->next = NULL;
@@ -59,29 +108,23 @@ g_node_new (gpointer data)
}
static void
-g_node_free (GNode *parent)
+g_nodes_free (GNode *node)
{
- GNode *node;
+ GNode *parent;
- node = parent->children;
-
- while (node)
+ parent = node;
+ while (1)
{
- register GNode *free_node;
-
- free_node = node;
- node = free_node->next;
- g_node_free (free_node);
+ if (parent->children)
+ g_nodes_free (parent->children);
+ if (parent->next)
+ parent = parent->next;
+ else
+ break;
}
- if (n_free_nodes < KEEP_NODES)
- {
- parent->next = free_nodes;
- free_nodes = parent;
- n_free_nodes++;
- }
- else
- g_chunk_free (parent, g_tree_node_chunk);
+ parent->next = current_allocator->free_nodes;
+ current_allocator->free_nodes = node;
}
void
@@ -92,7 +135,7 @@ g_node_destroy (GNode *root)
if (!G_NODE_IS_ROOT (root))
g_node_unlink (root);
- g_node_free (root);
+ g_nodes_free (root);
}
void
diff --git a/glib/gslist.c b/glib/gslist.c
index 6a76d22a6..4efe2a575 100644
--- a/glib/gslist.c
+++ b/glib/gslist.c
@@ -19,75 +19,103 @@
#include "glib.h"
-typedef struct _GRealListAllocator GRealListAllocator;
-
-struct _GRealListAllocator
+struct _GAllocator /* from gmem.c */
{
- GMemChunk *list_mem_chunk;
- GSList *free_list;
+ gchar *name;
+ guint16 n_preallocs;
+ guint is_unused : 1;
+ guint type : 4;
+ GAllocator *last;
+ GMemChunk *mem_chunk;
+ GSList *free_lists; /* implementation specific */
};
+static GAllocator *current_allocator = NULL;
-static GRealListAllocator *default_allocator = NULL;
-static GRealListAllocator *current_allocator = NULL;
-
-GListAllocator*
-g_slist_set_allocator (GListAllocator* fallocator)
+void
+g_slist_push_allocator (GAllocator *allocator)
{
- GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
- GRealListAllocator* old_allocator = current_allocator;
+ g_return_if_fail (allocator != NULL);
+ g_return_if_fail (allocator->is_unused == TRUE);
- if (allocator)
- current_allocator = allocator;
- else
+ if (allocator->type != G_ALLOCATOR_SLIST)
{
- if (!default_allocator)
- default_allocator = (GRealListAllocator*) g_list_allocator_new ();
- current_allocator = default_allocator;
+ allocator->type = G_ALLOCATOR_SLIST;
+ if (allocator->mem_chunk)
+ {
+ g_mem_chunk_destroy (allocator->mem_chunk);
+ allocator->mem_chunk = NULL;
+ }
}
- if (!current_allocator->list_mem_chunk)
- current_allocator->list_mem_chunk = g_mem_chunk_new ("slist mem chunk",
- sizeof (GSList),
- 1024,
- G_ALLOC_ONLY);
+ 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;
+ }
- return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator);
+ allocator->is_unused = FALSE;
+ allocator->last = current_allocator;
+ current_allocator = allocator;
}
+void
+g_slist_pop_allocator (void)
+{
+ if (current_allocator)
+ {
+ GAllocator *allocator;
+
+ allocator = current_allocator;
+ current_allocator = allocator->last;
+ allocator->last = NULL;
+ allocator->is_unused = TRUE;
+ }
+}
GSList*
g_slist_alloc (void)
{
- GSList *new_list;
+ GSList *list;
+
+ if (!current_allocator)
+ g_slist_push_allocator (g_allocator_new ("GLib default GSList allocator", 1024));
- g_slist_set_allocator (NULL);
- if (current_allocator->free_list)
+ if (!current_allocator->free_lists)
{
- new_list = current_allocator->free_list;
- current_allocator->free_list = current_allocator->free_list->next;
+ list = g_chunk_new (GSList, current_allocator->mem_chunk);
+ list->data = NULL;
}
else
{
- new_list = g_chunk_new (GSList, current_allocator->list_mem_chunk);
+ 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;
+ }
}
+ list->next = NULL;
- new_list->data = NULL;
- new_list->next = NULL;
-
- return new_list;
+ return list;
}
void
g_slist_free (GSList *list)
{
- GSList *last;
-
if (list)
{
- last = g_slist_last (list);
- last->next = current_allocator->free_list;
- current_allocator->free_list = list;
+ list->data = list->next;
+ list->next = current_allocator->free_lists;
+ current_allocator->free_lists = list;
}
}
@@ -96,8 +124,9 @@ g_slist_free_1 (GSList *list)
{
if (list)
{
- list->next = current_allocator->free_list;
- current_allocator->free_list = list;
+ list->data = NULL;
+ list->next = current_allocator->free_lists;
+ current_allocator->free_lists = list;
}
}
diff --git a/glib/gstring.c b/glib/gstring.c
index 39e43e21c..fa84fe7a2 100644
--- a/glib/gstring.c
+++ b/glib/gstring.c
@@ -106,14 +106,10 @@ g_string_chunk_free (GStringChunk *fchunk)
if (chunk->storage_list)
{
- GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
-
for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
g_free (tmp_list->data);
g_slist_free (chunk->storage_list);
-
- g_slist_set_allocator (tmp_allocator);
}
if (chunk->const_table)
@@ -134,7 +130,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
if ((chunk->storage_next + len + 1) > chunk->this_size)
{
- GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
gint new_size = chunk->default_size;
while (new_size < len+1)
@@ -145,8 +140,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
chunk->this_size = new_size;
chunk->storage_next = 0;
-
- g_slist_set_allocator (tmp_allocator);
}
pos = ((char*)chunk->storage_list->data) + chunk->storage_next;
diff --git a/glib/gtree.c b/glib/gtree.c
index 0d7f78cf9..4d9e98a0b 100644
--- a/glib/gtree.c
+++ b/glib/gtree.c
@@ -79,7 +79,51 @@ static void g_tree_node_check (GTreeNode *node);
static GMemChunk *node_mem_chunk = NULL;
-static GSList *node_free_list = NULL;
+static GTreeNode *node_free_list = NULL;
+
+
+static GTreeNode*
+g_tree_node_new (gpointer key,
+ gpointer value)
+{
+ GTreeNode *node;
+
+ 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);
+ }
+
+ node->balance = 0;
+ node->left = NULL;
+ node->right = NULL;
+ node->key = key;
+ node->value = value;
+
+ return node;
+}
+
+static void
+g_tree_node_destroy (GTreeNode *node)
+{
+ if (node)
+ {
+ g_tree_node_destroy (node->right);
+ g_tree_node_destroy (node->left);
+ node->right = node_free_list;
+ node_free_list = node;
+ }
+}
GTree*
@@ -230,55 +274,6 @@ g_tree_nnodes (GTree *tree)
return 0;
}
-
-static GTreeNode*
-g_tree_node_new (gpointer key,
- gpointer value)
-{
- GTreeNode *node;
- GSList *tmp_list;
-
- if (node_free_list)
- {
- tmp_list = node_free_list;
- node_free_list = node_free_list->next;
-
- node = tmp_list->data;
-
- {
- GListAllocator *tmp_allocator = g_list_set_allocator (NULL);
- g_slist_free_1 (tmp_list);
- g_list_set_allocator (tmp_allocator);
- }
- }
- else
- {
- if (!node_mem_chunk)
- node_mem_chunk = g_mem_chunk_new ("tree node mem chunk", sizeof (GTreeNode), 1024, G_ALLOC_ONLY);
-
- node = g_chunk_new (GTreeNode, node_mem_chunk);
- }
-
- node->balance = 0;
- node->left = NULL;
- node->right = NULL;
- node->key = key;
- node->value = value;
-
- return node;
-}
-
-static void
-g_tree_node_destroy (GTreeNode *node)
-{
- if (node)
- {
- node_free_list = g_slist_prepend (node_free_list, node);
- g_tree_node_destroy (node->right);
- g_tree_node_destroy (node->left);
- }
-}
-
static GTreeNode*
g_tree_node_insert (GTreeNode *node,
GCompareFunc compare,
@@ -352,7 +347,6 @@ g_tree_node_remove (GTreeNode *node,
GCompareFunc compare,
gpointer key)
{
- GTreeNode *garbage;
GTreeNode *new_root;
gint old_balance;
gint cmp;
@@ -363,6 +357,8 @@ g_tree_node_remove (GTreeNode *node,
cmp = (* compare) (key, node->key);
if (cmp == 0)
{
+ GTreeNode *garbage;
+
garbage = node;
if (!node->right)
@@ -379,7 +375,8 @@ g_tree_node_remove (GTreeNode *node,
node = g_tree_node_restore_right_balance (new_root, old_balance);
}
- node_free_list = g_slist_prepend (node_free_list, garbage);
+ garbage->right = node_free_list;
+ node_free_list = garbage;
}
else if (cmp < 0)
{
diff --git a/glist.c b/glist.c
index ee9ad695c..ab69826a2 100644
--- a/glist.c
+++ b/glist.c
@@ -19,99 +19,104 @@
#include "glib.h"
-typedef struct _GRealListAllocator GRealListAllocator;
-
-struct _GRealListAllocator
+struct _GAllocator /* from gmem.c */
{
- GMemChunk *list_mem_chunk;
- GList *free_list;
+ 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;
-static GRealListAllocator *default_allocator = NULL;
-static GRealListAllocator *current_allocator = NULL;
+void
+g_list_push_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;
+ }
+ }
-GListAllocator*
-g_list_allocator_new (void)
-{
- GRealListAllocator* allocator = g_new (GRealListAllocator, 1);
-
- allocator->list_mem_chunk = NULL;
- allocator->free_list = NULL;
-
- return (GListAllocator*) allocator;
-}
+ 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;
+ }
-void
-g_list_allocator_free (GListAllocator* fallocator)
-{
- GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
-
- if (allocator && allocator->list_mem_chunk)
- g_mem_chunk_destroy (allocator->list_mem_chunk);
- if (allocator)
- g_free (allocator);
+ allocator->is_unused = FALSE;
+ allocator->last = current_allocator;
+ current_allocator = allocator;
}
-GListAllocator*
-g_list_set_allocator (GListAllocator* fallocator)
+void
+g_list_pop_allocator (void)
{
- GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
- GRealListAllocator* old_allocator = current_allocator;
-
- if (allocator)
- current_allocator = allocator;
- else
+ if (current_allocator)
{
- if (!default_allocator)
- default_allocator = (GRealListAllocator*) g_list_allocator_new ();
- current_allocator = default_allocator;
+ GAllocator *allocator;
+
+ allocator = current_allocator;
+ current_allocator = allocator->last;
+ allocator->last = NULL;
+ allocator->is_unused = TRUE;
}
-
- if (!current_allocator->list_mem_chunk)
- current_allocator->list_mem_chunk = g_mem_chunk_new ("list mem chunk",
- sizeof (GList),
- 1024,
- G_ALLOC_ONLY);
-
- return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator);
}
-
GList*
g_list_alloc (void)
{
- GList *new_list;
-
- g_list_set_allocator (NULL);
- if (current_allocator->free_list)
+ GList *list;
+
+ if (!current_allocator)
+ g_list_push_allocator (g_allocator_new ("GLib default GList allocator", 1024));
+
+ if (!current_allocator->free_lists)
{
- new_list = current_allocator->free_list;
- current_allocator->free_list = current_allocator->free_list->next;
+ list = g_chunk_new (GList, current_allocator->mem_chunk);
+ list->data = NULL;
}
else
{
- new_list = g_chunk_new (GList, current_allocator->list_mem_chunk);
+ 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;
+ }
}
+ list->next = NULL;
+ list->prev = NULL;
- new_list->data = NULL;
- new_list->next = NULL;
- new_list->prev = NULL;
-
- return new_list;
+ return list;
}
void
g_list_free (GList *list)
{
- GList *last;
-
if (list)
{
- last = g_list_last (list);
- last->next = current_allocator->free_list;
- current_allocator->free_list = list;
+ list->data = list->next;
+ list->next = current_allocator->free_lists;
+ current_allocator->free_lists = list;
}
}
@@ -120,8 +125,9 @@ g_list_free_1 (GList *list)
{
if (list)
{
- list->next = current_allocator->free_list;
- current_allocator->free_list = list;
+ list->data = NULL;
+ list->next = current_allocator->free_lists;
+ current_allocator->free_lists = list;
}
}
diff --git a/gmem.c b/gmem.c
index cd7f47ea9..c29ee660f 100644
--- a/gmem.c
+++ b/gmem.c
@@ -894,3 +894,49 @@ g_mem_chunk_area_search (GMemArea *a,
}
return -1;
}
+
+/* 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;
+}
+
+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);
+}
diff --git a/gnode.c b/gnode.c
index dea428da6..9f6e544ba 100644
--- a/gnode.c
+++ b/gnode.c
@@ -21,33 +21,82 @@
*/
#include "glib.h"
+/* 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 */
+};
+
+static GAllocator *current_allocator = NULL;
+
+void
+g_node_push_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;
+ }
+ }
-#define KEEP_NODES (1024)
+ 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;
+ allocator->last = current_allocator;
+ current_allocator = allocator;
+}
+
+void
+g_node_pop_allocator (void)
+{
+ if (current_allocator)
+ {
+ GAllocator *allocator;
-/* --- variables --- */
-static GMemChunk *g_tree_node_chunk = NULL;
-static GNode *free_nodes = NULL;
-static guint n_free_nodes = 0;
+ allocator = current_allocator;
+ current_allocator = allocator->last;
+ allocator->last = NULL;
+ allocator->is_unused = TRUE;
+ }
+}
/* --- functions --- */
GNode*
g_node_new (gpointer data)
{
- register GNode *node;
-
- if (!g_tree_node_chunk)
- g_tree_node_chunk = g_mem_chunk_create (GNode, 1024, G_ALLOC_AND_FREE);
-
- if (n_free_nodes)
+ GNode *node;
+
+ if (!current_allocator)
+ g_node_push_allocator (g_allocator_new ("GLib default GNode allocator", 1024));
+
+ if (!current_allocator->free_nodes)
+ node = g_chunk_new (GNode, current_allocator->mem_chunk);
+ else
{
- node = free_nodes;
- free_nodes = free_nodes->next;
- n_free_nodes--;
+ node = current_allocator->free_nodes;
+ current_allocator->free_nodes = node->next;
}
- else
- node = g_chunk_new (GNode, g_tree_node_chunk);
node->data = data;
node->next = NULL;
@@ -59,29 +108,23 @@ g_node_new (gpointer data)
}
static void
-g_node_free (GNode *parent)
+g_nodes_free (GNode *node)
{
- GNode *node;
+ GNode *parent;
- node = parent->children;
-
- while (node)
+ parent = node;
+ while (1)
{
- register GNode *free_node;
-
- free_node = node;
- node = free_node->next;
- g_node_free (free_node);
+ if (parent->children)
+ g_nodes_free (parent->children);
+ if (parent->next)
+ parent = parent->next;
+ else
+ break;
}
- if (n_free_nodes < KEEP_NODES)
- {
- parent->next = free_nodes;
- free_nodes = parent;
- n_free_nodes++;
- }
- else
- g_chunk_free (parent, g_tree_node_chunk);
+ parent->next = current_allocator->free_nodes;
+ current_allocator->free_nodes = node;
}
void
@@ -92,7 +135,7 @@ g_node_destroy (GNode *root)
if (!G_NODE_IS_ROOT (root))
g_node_unlink (root);
- g_node_free (root);
+ g_nodes_free (root);
}
void
diff --git a/gslist.c b/gslist.c
index 6a76d22a6..4efe2a575 100644
--- a/gslist.c
+++ b/gslist.c
@@ -19,75 +19,103 @@
#include "glib.h"
-typedef struct _GRealListAllocator GRealListAllocator;
-
-struct _GRealListAllocator
+struct _GAllocator /* from gmem.c */
{
- GMemChunk *list_mem_chunk;
- GSList *free_list;
+ gchar *name;
+ guint16 n_preallocs;
+ guint is_unused : 1;
+ guint type : 4;
+ GAllocator *last;
+ GMemChunk *mem_chunk;
+ GSList *free_lists; /* implementation specific */
};
+static GAllocator *current_allocator = NULL;
-static GRealListAllocator *default_allocator = NULL;
-static GRealListAllocator *current_allocator = NULL;
-
-GListAllocator*
-g_slist_set_allocator (GListAllocator* fallocator)
+void
+g_slist_push_allocator (GAllocator *allocator)
{
- GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
- GRealListAllocator* old_allocator = current_allocator;
+ g_return_if_fail (allocator != NULL);
+ g_return_if_fail (allocator->is_unused == TRUE);
- if (allocator)
- current_allocator = allocator;
- else
+ if (allocator->type != G_ALLOCATOR_SLIST)
{
- if (!default_allocator)
- default_allocator = (GRealListAllocator*) g_list_allocator_new ();
- current_allocator = default_allocator;
+ allocator->type = G_ALLOCATOR_SLIST;
+ if (allocator->mem_chunk)
+ {
+ g_mem_chunk_destroy (allocator->mem_chunk);
+ allocator->mem_chunk = NULL;
+ }
}
- if (!current_allocator->list_mem_chunk)
- current_allocator->list_mem_chunk = g_mem_chunk_new ("slist mem chunk",
- sizeof (GSList),
- 1024,
- G_ALLOC_ONLY);
+ 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;
+ }
- return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator);
+ allocator->is_unused = FALSE;
+ allocator->last = current_allocator;
+ current_allocator = allocator;
}
+void
+g_slist_pop_allocator (void)
+{
+ if (current_allocator)
+ {
+ GAllocator *allocator;
+
+ allocator = current_allocator;
+ current_allocator = allocator->last;
+ allocator->last = NULL;
+ allocator->is_unused = TRUE;
+ }
+}
GSList*
g_slist_alloc (void)
{
- GSList *new_list;
+ GSList *list;
+
+ if (!current_allocator)
+ g_slist_push_allocator (g_allocator_new ("GLib default GSList allocator", 1024));
- g_slist_set_allocator (NULL);
- if (current_allocator->free_list)
+ if (!current_allocator->free_lists)
{
- new_list = current_allocator->free_list;
- current_allocator->free_list = current_allocator->free_list->next;
+ list = g_chunk_new (GSList, current_allocator->mem_chunk);
+ list->data = NULL;
}
else
{
- new_list = g_chunk_new (GSList, current_allocator->list_mem_chunk);
+ 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;
+ }
}
+ list->next = NULL;
- new_list->data = NULL;
- new_list->next = NULL;
-
- return new_list;
+ return list;
}
void
g_slist_free (GSList *list)
{
- GSList *last;
-
if (list)
{
- last = g_slist_last (list);
- last->next = current_allocator->free_list;
- current_allocator->free_list = list;
+ list->data = list->next;
+ list->next = current_allocator->free_lists;
+ current_allocator->free_lists = list;
}
}
@@ -96,8 +124,9 @@ g_slist_free_1 (GSList *list)
{
if (list)
{
- list->next = current_allocator->free_list;
- current_allocator->free_list = list;
+ list->data = NULL;
+ list->next = current_allocator->free_lists;
+ current_allocator->free_lists = list;
}
}
diff --git a/gstring.c b/gstring.c
index 39e43e21c..fa84fe7a2 100644
--- a/gstring.c
+++ b/gstring.c
@@ -106,14 +106,10 @@ g_string_chunk_free (GStringChunk *fchunk)
if (chunk->storage_list)
{
- GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
-
for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
g_free (tmp_list->data);
g_slist_free (chunk->storage_list);
-
- g_slist_set_allocator (tmp_allocator);
}
if (chunk->const_table)
@@ -134,7 +130,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
if ((chunk->storage_next + len + 1) > chunk->this_size)
{
- GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
gint new_size = chunk->default_size;
while (new_size < len+1)
@@ -145,8 +140,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
chunk->this_size = new_size;
chunk->storage_next = 0;
-
- g_slist_set_allocator (tmp_allocator);
}
pos = ((char*)chunk->storage_list->data) + chunk->storage_next;
diff --git a/gtree.c b/gtree.c
index 0d7f78cf9..4d9e98a0b 100644
--- a/gtree.c
+++ b/gtree.c
@@ -79,7 +79,51 @@ static void g_tree_node_check (GTreeNode *node);
static GMemChunk *node_mem_chunk = NULL;
-static GSList *node_free_list = NULL;
+static GTreeNode *node_free_list = NULL;
+
+
+static GTreeNode*
+g_tree_node_new (gpointer key,
+ gpointer value)
+{
+ GTreeNode *node;
+
+ 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);
+ }
+
+ node->balance = 0;
+ node->left = NULL;
+ node->right = NULL;
+ node->key = key;
+ node->value = value;
+
+ return node;
+}
+
+static void
+g_tree_node_destroy (GTreeNode *node)
+{
+ if (node)
+ {
+ g_tree_node_destroy (node->right);
+ g_tree_node_destroy (node->left);
+ node->right = node_free_list;
+ node_free_list = node;
+ }
+}
GTree*
@@ -230,55 +274,6 @@ g_tree_nnodes (GTree *tree)
return 0;
}
-
-static GTreeNode*
-g_tree_node_new (gpointer key,
- gpointer value)
-{
- GTreeNode *node;
- GSList *tmp_list;
-
- if (node_free_list)
- {
- tmp_list = node_free_list;
- node_free_list = node_free_list->next;
-
- node = tmp_list->data;
-
- {
- GListAllocator *tmp_allocator = g_list_set_allocator (NULL);
- g_slist_free_1 (tmp_list);
- g_list_set_allocator (tmp_allocator);
- }
- }
- else
- {
- if (!node_mem_chunk)
- node_mem_chunk = g_mem_chunk_new ("tree node mem chunk", sizeof (GTreeNode), 1024, G_ALLOC_ONLY);
-
- node = g_chunk_new (GTreeNode, node_mem_chunk);
- }
-
- node->balance = 0;
- node->left = NULL;
- node->right = NULL;
- node->key = key;
- node->value = value;
-
- return node;
-}
-
-static void
-g_tree_node_destroy (GTreeNode *node)
-{
- if (node)
- {
- node_free_list = g_slist_prepend (node_free_list, node);
- g_tree_node_destroy (node->right);
- g_tree_node_destroy (node->left);
- }
-}
-
static GTreeNode*
g_tree_node_insert (GTreeNode *node,
GCompareFunc compare,
@@ -352,7 +347,6 @@ g_tree_node_remove (GTreeNode *node,
GCompareFunc compare,
gpointer key)
{
- GTreeNode *garbage;
GTreeNode *new_root;
gint old_balance;
gint cmp;
@@ -363,6 +357,8 @@ g_tree_node_remove (GTreeNode *node,
cmp = (* compare) (key, node->key);
if (cmp == 0)
{
+ GTreeNode *garbage;
+
garbage = node;
if (!node->right)
@@ -379,7 +375,8 @@ g_tree_node_remove (GTreeNode *node,
node = g_tree_node_restore_right_balance (new_root, old_balance);
}
- node_free_list = g_slist_prepend (node_free_list, garbage);
+ garbage->right = node_free_list;
+ node_free_list = garbage;
}
else if (cmp < 0)
{