summaryrefslogtreecommitdiff
path: root/src/arch/sharing
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-04-20 18:52:01 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-04-20 18:52:01 (GMT)
commit8e5c8417e8ef79c1b475cb1b86a1754b24f9af78 (patch)
tree650a39bde7a5367995b471a562aa766febd505bc /src/arch/sharing
parentc177597d6da5dedb32aa176e8370db8ffb7f87aa (diff)
Shared immediate operands in order to avoid useless allocations.
Diffstat (limited to 'src/arch/sharing')
-rw-r--r--src/arch/sharing/container-int.h2
-rw-r--r--src/arch/sharing/container.c12
-rw-r--r--src/arch/sharing/container.h2
-rw-r--r--src/arch/sharing/instance-int.h4
-rw-r--r--src/arch/sharing/instance.c24
-rw-r--r--src/arch/sharing/instance.h3
-rw-r--r--src/arch/sharing/manager.c101
-rw-r--r--src/arch/sharing/manager.h6
8 files changed, 140 insertions, 14 deletions
diff --git a/src/arch/sharing/container-int.h b/src/arch/sharing/container-int.h
index 8e4ccbd..bc67bf6 100644
--- a/src/arch/sharing/container-int.h
+++ b/src/arch/sharing/container-int.h
@@ -30,7 +30,7 @@
/* Assure la mise à jour du contenu d'un intégrateur. */
-typedef void (* replace_shared_fc) (GShareContainer *, GSharedInstance *, GSharedInstance *);
+typedef bool (* replace_shared_fc) (GShareContainer *, GSharedInstance *, GSharedInstance *);
/* Règles de partage d'une instance GObject (interface) */
diff --git a/src/arch/sharing/container.c b/src/arch/sharing/container.c
index f027673..5ff62b7 100644
--- a/src/arch/sharing/container.c
+++ b/src/arch/sharing/container.c
@@ -66,22 +66,28 @@ static void g_share_container_default_init(GShareContainerInterface *iface)
* *
* Description : Assure la mise à jour du contenu d'un intégrateur. *
* *
-* Retour : - *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_share_container_replace(GShareContainer *container, GSharedInstance *old, GSharedInstance *new)
+bool g_share_container_replace(GShareContainer *container, GSharedInstance *old, GSharedInstance *new)
{
+ bool result; /* Bilan à retourner */
GShareContainerIface *iface; /* Interface utilisée */
if (old != new)
{
iface = G_SHARE_CONTAINER_GET_IFACE(container);
- iface->replace(container, old, new);
+ result = iface->replace(container, old, new);
}
+ else
+ result = false;
+
+ return result;
+
}
diff --git a/src/arch/sharing/container.h b/src/arch/sharing/container.h
index 06d55a1..3312f9d 100644
--- a/src/arch/sharing/container.h
+++ b/src/arch/sharing/container.h
@@ -52,7 +52,7 @@ typedef struct _GShareContainerIface GShareContainerIface;
GType g_share_container_get_type(void) G_GNUC_CONST;
/* Assure la mise à jour du contenu d'un intégrateur. */
-void g_share_container_replace(GShareContainer *, GSharedInstance *, GSharedInstance *);
+bool g_share_container_replace(GShareContainer *, GSharedInstance *, GSharedInstance *);
diff --git a/src/arch/sharing/instance-int.h b/src/arch/sharing/instance-int.h
index c3ebae5..f9a91ba 100644
--- a/src/arch/sharing/instance-int.h
+++ b/src/arch/sharing/instance-int.h
@@ -32,6 +32,9 @@
/* Initialise un nouvel objet partagé avec des informations. */
typedef bool (* init_shared_fc) (GSharedInstance *, const GSharedInstance *);
+/* Procède à l'initialisation de l'interface de partage. */
+typedef void (* qck_copy_shared_fc) (const GSharedInstance *, GSharedInstance *);
+
/* Fournit la valeur du compteur de partage. */
typedef unsigned int (* get_shared_ref_fc) (const GSharedInstance *);
@@ -51,6 +54,7 @@ struct _GSharedInstanceIface
GTypeInterface base_iface; /* A laisser en premier */
init_shared_fc init; /* Initialisation de l'objet */
+ qck_copy_shared_fc qck_copy; /* Copie minimale des détails */
get_shared_ref_fc get_ref; /* Obtention du compteur */
inc_shared_ref_fc inc_ref; /* Incrémentation du compteur */
diff --git a/src/arch/sharing/instance.c b/src/arch/sharing/instance.c
index abcb653..c0038aa 100644
--- a/src/arch/sharing/instance.c
+++ b/src/arch/sharing/instance.c
@@ -88,6 +88,30 @@ bool g_shared_instance_init(GSharedInstance *instance, const GSharedInstance *te
/******************************************************************************
* *
* Paramètres : instance = objet partagé à consulter. *
+* template = informations à retrouver intégralement. *
+* *
+* Description : Réalise une copie minimale d'un contenu partagé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_shared_instance_quickly_copy(const GSharedInstance *instance, GSharedInstance *template)
+{
+ GSharedInstanceIface *iface; /* Interface utilisée */
+
+ iface = G_SHARED_INSTANCE_GET_IFACE(instance);
+
+ iface->qck_copy(instance, template);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instance = objet partagé à consulter. *
* *
* Description : Fournit la valeur du compteur de partage. *
* *
diff --git a/src/arch/sharing/instance.h b/src/arch/sharing/instance.h
index b79fa33..fdc94d7 100644
--- a/src/arch/sharing/instance.h
+++ b/src/arch/sharing/instance.h
@@ -51,6 +51,9 @@ GType g_shared_instance_get_type(void) G_GNUC_CONST;
/* Initialise un nouvel objet partagé avec des informations. */
bool g_shared_instance_init(GSharedInstance *, const GSharedInstance *);
+/* Réalise une copie minimale d'un contenu partagé. */
+void g_shared_instance_quickly_copy(const GSharedInstance *, GSharedInstance *);
+
/* Fournit la valeur du compteur de partage. */
unsigned int g_shared_instance_get_references(const GSharedInstance *);
diff --git a/src/arch/sharing/manager.c b/src/arch/sharing/manager.c
index 43e7e25..952fc33 100644
--- a/src/arch/sharing/manager.c
+++ b/src/arch/sharing/manager.c
@@ -235,8 +235,8 @@ GSharedInstance *g_share_manager_get(GShareManager *manager, GSharedInstance *te
{
g_shared_instance_inc_references(result);
- manager->instances = (GSharedInstance **)_qinsert(manager->instances, &manager->count,
- sizeof(GSharedInstance *), &result, index);
+ manager->instances = _qinsert(manager->instances, &manager->count,
+ sizeof(GSharedInstance *), &result, index);
}
@@ -276,13 +276,96 @@ GSharedInstance *g_share_manager_get(GShareManager *manager, GSharedInstance *te
GSharedInstance *g_share_manager_update(GShareManager *manager, GSharedInstance *old, GSharedInstance *template, GShareContainer *container)
{
GSharedInstance *result; /* Nouvelle instance à renvoyer*/
+ bool replaced; /* Remplacement effectué ? */
result = g_share_manager_get(manager, template);
if (container != NULL)
- g_share_container_replace(container, old, result);
+ replaced = g_share_container_replace(container, old, result);
+ else
+ replaced = false;
+
+ if (replaced)
+ g_share_manager_put(manager, old);
- g_share_manager_put(manager, old);
+ else
+ {
+ g_share_manager_put(manager, result);
+ result = old;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = gestionnaire d'instance à consulter. *
+* instance = instance partagée vouée à évoluer. *
+* *
+* Description : Prépare une modification légère et locale d'un élément. *
+* *
+* Retour : Indice de l'élément prêt à être modifié. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t g_share_manager_prepare_light_update(GShareManager *manager, GSharedInstance *instance)
+{
+ size_t result; /* Indice courant à retourner */
+#ifndef NDEBUG
+ bool found; /* Validation de présence */
+#endif
+
+ g_mutex_lock(&manager->access);
+
+#ifndef NDEBUG
+
+ found = bsearch_index(&instance, manager->instances, manager->count,sizeof(GSharedInstance *),
+ (__compar_fn_t)g_shared_instance_quickly_compare, &result);
+
+ assert(found);
+
+#else
+
+ bsearch_index(&instance, manager->instances, manager->count,sizeof(GSharedInstance *),
+ (__compar_fn_t)g_shared_instance_quickly_compare, &result);
+
+#endif
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = gestionnaire d'instance à consulter. *
+* instance = instance partagée vouée à évoluer. *
+* index = indice de la place de l'élément avant modifcation.*
+* *
+* Description : Conclut une modification légère et locale d'un élément. *
+* *
+* Retour : Indice de l'élément prêt à être modifié. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GSharedInstance *g_share_manager_complete_light_update(GShareManager *manager, GSharedInstance *instance, size_t index)
+{
+ GSharedInstance *result; /* Nouvelle instance à renvoyer*/
+
+ manager->instances = _qdelete(manager->instances, &manager->count,
+ sizeof(GSharedInstance *), index);
+
+ g_mutex_unlock(&manager->access);
+
+ result = g_share_manager_get(manager, instance);
+
+ g_object_unref(G_OBJECT(instance));
return result;
@@ -310,12 +393,12 @@ void g_share_manager_put(GShareManager *manager, GSharedInstance *shared)
if (g_shared_instance_get_references(shared) == 1)
{
- g_object_unref(G_OBJECT(shared));
+ manager->instances = qdelete(manager->instances, &manager->count,
+ sizeof(GSharedInstance *),
+ (__compar_fn_t)g_shared_instance_quickly_compare,
+ &shared);
- manager->instances = (GSharedInstance **)qdelete(manager->instances, &manager->count,
- sizeof(GSharedInstance *),
- (__compar_fn_t)g_shared_instance_quickly_compare,
- &shared);
+ g_object_unref(G_OBJECT(shared));
}
diff --git a/src/arch/sharing/manager.h b/src/arch/sharing/manager.h
index 959087d..f2fcea6 100644
--- a/src/arch/sharing/manager.h
+++ b/src/arch/sharing/manager.h
@@ -65,6 +65,12 @@ GSharedInstance *g_share_manager_get(GShareManager *, GSharedInstance *);
/* Met à jour une instance partagée. */
GSharedInstance *g_share_manager_update(GShareManager *, GSharedInstance *, GSharedInstance *, GShareContainer *);
+/* Prépare une modification légère et locale d'un élément. */
+size_t g_share_manager_prepare_light_update(GShareManager *, GSharedInstance *);
+
+/* Conclut une modification légère et locale d'un élément. */
+GSharedInstance *g_share_manager_complete_light_update(GShareManager *, GSharedInstance *, size_t);
+
/* Abandonne un usage d'une instance partagée. */
void g_share_manager_put(GShareManager *, GSharedInstance *);