summaryrefslogtreecommitdiff
path: root/src/arch/sharing/manager.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-12-18 15:32:27 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-12-18 15:32:27 (GMT)
commitb0bcf250999b2242019f137e38f52390a86e71cd (patch)
treef3436a3ddbbd4773005ecb891630a815ed001341 /src/arch/sharing/manager.c
parent6bde4016160057a22234d4ed698903dca52ce162 (diff)
Shared all Dalvik operands between all their users.
Diffstat (limited to 'src/arch/sharing/manager.c')
-rw-r--r--src/arch/sharing/manager.c128
1 files changed, 127 insertions, 1 deletions
diff --git a/src/arch/sharing/manager.c b/src/arch/sharing/manager.c
index 9f6ec39..2e92766 100644
--- a/src/arch/sharing/manager.c
+++ b/src/arch/sharing/manager.c
@@ -25,6 +25,9 @@
#include <assert.h>
+#ifdef DEBUG_DUMP_STATS
+# include <stdio.h>
+#endif
@@ -34,6 +37,7 @@ struct _GShareManager
GObject parent; /* A laisser en premier */
GHashTable *table; /* Collection de partages */
+ GMutex access; /* Accès à la table */
GType managed; /* Type d'instances gérées */
@@ -103,6 +107,7 @@ static void g_share_manager_class_init(GShareManagerClass *class)
static void g_share_manager_init(GShareManager *manager)
{
+ g_mutex_init(&manager->access);
}
@@ -122,6 +127,7 @@ static void g_share_manager_init(GShareManager *manager)
static void g_share_manager_dispose(GShareManager *manager)
{
g_hash_table_unref(manager->table);
+ g_mutex_clear(&manager->access);
G_OBJECT_CLASS(g_share_manager_parent_class)->dispose(G_OBJECT(manager));
@@ -190,7 +196,7 @@ GShareManager *g_share_manager_new(GType type)
* *
******************************************************************************/
-GSharedInstance *g_share_manager_get(const GShareManager *manager, const void *info)
+GSharedInstance *g_share_manager_get(GShareManager *manager, const void *info)
{
GSharedInstance *result; /* Trouvaille à retourner */
gpointer found; /* Elément correspondant ? */
@@ -204,6 +210,8 @@ GSharedInstance *g_share_manager_get(const GShareManager *manager, const void *i
return g_shared_instance_compare_info(key, nfo);
}
+ g_mutex_lock(&manager->access);
+
found = g_hash_table_find(manager->table, (GHRFunc)find_shared_matching_info, (void *)info);
if (found == NULL)
@@ -220,6 +228,7 @@ GSharedInstance *g_share_manager_get(const GShareManager *manager, const void *i
else
{
+ g_shared_instance_inc_references(result);
#ifndef NDEBUG
new = g_hash_table_add(manager->table, result);
@@ -241,6 +250,123 @@ GSharedInstance *g_share_manager_get(const GShareManager *manager, const void *i
g_shared_instance_inc_references(result);
}
+ g_mutex_unlock(&manager->access);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = gestionnaire d'instance à consulter. *
+* old = ancienne instance partagée à faire évoluer. *
+* info = informations à retrouver intégralement. *
+* container = propriétaire de l'ancienne version à contacter. *
+* *
+* Description : Met à jour une instance partagée. *
+* *
+* Retour : Instance existante déjà partagée ou nouvellement créée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GSharedInstance *g_share_manager_update(GShareManager *manager, GSharedInstance *old, const void *info, GShareContainer *container)
+{
+ GSharedInstance *result; /* Nouvelle instance à renvoyer*/
+
+ result = g_share_manager_get(manager, info);
+
+ if (container != NULL)
+ g_share_container_replace(container, old, result);
+
+ g_share_manager_put(manager, old);
+
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = gestionnaire d'instance à consulter. *
+* shared = instance partagée à libérer. *
+* *
+* Description : Abandonne un usage d'une instance partagée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_share_manager_put(GShareManager *manager, GSharedInstance *shared)
+{
+#ifndef NDEBUG
+ gboolean found; /* Présence de partage existant*/
+#endif
+
+ g_mutex_lock(&manager->access);
+
+ g_shared_instance_dec_references(shared);
+
+ if (g_shared_instance_get_references(shared) == 1)
+ {
+#ifndef NDEBUG
+ found = g_hash_table_remove(manager->table, shared);
+ assert(found);
+#else
+ g_hash_table_remove(manager->table, shared);
+#endif
+ }
+
+ g_mutex_unlock(&manager->access);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = gestionnaire d'instance à consulter. *
+* *
+* Description : Imprime des statistiques d'utilisation du gestionnaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+#ifdef DEBUG_DUMP_STATS
+void g_share_manager_dump_stats(GShareManager *manager)
+{
+ unsigned int counter; /* Quantité nécessaire */
+ GTypeQuery query; /* Informations sur un type */
+ guint size; /* Taille de la table */
+
+ void count_shared_instances(const GSharedInstance *key, gpointer unused, unsigned int *c)
+ {
+ *c += g_shared_instance_get_references(key);
+ }
+
+ counter = 0;
+
+ g_mutex_lock(&manager->access);
+
+ g_hash_table_foreach(manager->table, (GHFunc)count_shared_instances, &counter);
+
+ size = g_hash_table_size(manager->table);
+
+ g_mutex_unlock(&manager->access);
+
+ g_type_query(manager->managed, &query);
+
+ printf("%s: current = %u / %u - needed = %u / %u (size=%u, saved=%u)\n",
+ query.type_name,
+ size, size * query.instance_size,
+ counter, counter * query.instance_size,
+ query.instance_size,
+ (counter - size) * query.instance_size);
+
+}
+#endif