From 9c1692c2604bf147d2b08877d8cebb1f077658e0 Mon Sep 17 00:00:00 2001 From: Tim Janik Date: Tue, 24 Nov 1998 12:18:22 +0000 Subject: removed the GListAllocator type and its g_*_allocator_*() function Tue Nov 24 09:40:00 1998 Tim Janik * 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. --- ChangeLog | 18 +++++++ ChangeLog.pre-2-0 | 18 +++++++ ChangeLog.pre-2-10 | 18 +++++++ ChangeLog.pre-2-12 | 18 +++++++ ChangeLog.pre-2-2 | 18 +++++++ ChangeLog.pre-2-4 | 18 +++++++ ChangeLog.pre-2-6 | 18 +++++++ ChangeLog.pre-2-8 | 18 +++++++ gdataset.c | 102 ++++++++++++++++++++++------------------ glib.h | 26 ++++++---- glib/gdataset.c | 102 ++++++++++++++++++++++------------------ glib/glib.h | 26 ++++++---- glib/glist.c | 136 ++++++++++++++++++++++++++++------------------------- glib/gmem.c | 46 ++++++++++++++++++ glib/gnode.c | 113 ++++++++++++++++++++++++++++++-------------- glib/gslist.c | 111 +++++++++++++++++++++++++++---------------- glib/gstring.c | 7 --- glib/gtree.c | 101 +++++++++++++++++++-------------------- glist.c | 136 ++++++++++++++++++++++++++++------------------------- gmem.c | 46 ++++++++++++++++++ gnode.c | 113 ++++++++++++++++++++++++++++++-------------- gslist.c | 111 +++++++++++++++++++++++++++---------------- gstring.c | 7 --- gtree.c | 101 +++++++++++++++++++-------------------- 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 + + * 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 * 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 + + * 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 * 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 + + * 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 * 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 + + * 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 * 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 + + * 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 * 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 + + * 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 * 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 + + * 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 * 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 + + * 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 * 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) { -- cgit v1.2.3