summaryrefslogtreecommitdiff
path: root/src/glibext
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-05-09 10:58:31 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-05-09 10:58:31 (GMT)
commit286878b36b5cf7a3f44251f62c94a57f0f29d3cf (patch)
treea38a8a349ae55797f9fe2a1c2e3fb20b37855136 /src/glibext
parent3014f4f91f660dd7eaf80c5634c8ffa8fe3e95ec (diff)
Handled the global work queue groups in a better way.
Diffstat (limited to 'src/glibext')
-rw-r--r--src/glibext/delayed.c74
-rw-r--r--src/glibext/delayed.h5
2 files changed, 34 insertions, 45 deletions
diff --git a/src/glibext/delayed.c b/src/glibext/delayed.c
index 9d67a7c..9bac68a 100644
--- a/src/glibext/delayed.c
+++ b/src/glibext/delayed.c
@@ -175,7 +175,7 @@ static void g_work_queue_dispose(GWorkQueue *);
static void g_work_queue_finalize(GWorkQueue *);
/* Donne l'assurance de l'existence d'un groupe de travail. */
-static GWorkGroup *g_work_queue_ensure_group_exists(GWorkQueue *, wgroup_id_t);
+static bool g_work_queue_ensure_group_exists(GWorkQueue *, wgroup_id_t);
/* Fournit le groupe de travail correspondant à un identifiant. */
static GWorkGroup *g_work_queue_find_group_for_id(GWorkQueue *, wgroup_id_t);
@@ -682,13 +682,11 @@ static bool g_work_group_is_empty(GWorkGroup *group)
* son utilisation par l'appelant.
*
* Il doit donc logiquement y avoir un autre verrou en amont et,
- * comme à priori on ne devrait pas bloquer le groupe principal
- * pour un traitement particulier, on ajoute ici une simple vérification
- * de bonne pratique.
+ * comme à priori on ne devrait pas bloquer les groupes principaux
+ * pour un traitement particulier, cette procédure ne devrait concerner
+ * que des groupes dynamiques.
*/
- assert(group->id != DEFAULT_WORK_GROUP);
-
g_mutex_lock(&group->mutex);
result = dl_list_empty(group->works);
@@ -936,24 +934,26 @@ GWorkQueue *g_work_queue_new(void)
* *
* Description : Donne l'assurance de l'existence d'un groupe de travail. *
* *
-* Retour : - *
+* Retour : true si un nouveau groupe a été constitué, false sinon. *
* *
* Remarques : Le verrou d'accès doit être posé par l'appelant. *
* *
******************************************************************************/
-static GWorkGroup *g_work_queue_ensure_group_exists(GWorkQueue *queue, wgroup_id_t id)
+static bool g_work_queue_ensure_group_exists(GWorkQueue *queue, wgroup_id_t id)
{
- GWorkGroup *result; /* Groupe en place à renvoyer */
bool found; /* Bilan des recherches */
size_t i; /* Boucle de parcours */
+ GWorkGroup *group; /* Groupe à consulter */
+
+ assert(!g_mutex_trylock(&queue->mutex));
found = false;
for (i = 0; i < queue->groups_count && !found; i++)
{
- result = queue->groups[i];
- found = (g_work_group_get_id(result) == id);
+ group = queue->groups[i];
+ found = (g_work_group_get_id(group) == id);
}
if (!found)
@@ -962,12 +962,12 @@ static GWorkGroup *g_work_queue_ensure_group_exists(GWorkQueue *queue, wgroup_id
queue->groups = (GWorkGroup **)realloc(queue->groups,
queue->groups_count * sizeof(GWorkGroup *));
- result = g_work_group_new(id);
- queue->groups[queue->groups_count - 1] = result;
+ group = g_work_group_new(id);
+ queue->groups[queue->groups_count - 1] = group;
}
- return result;
+ return !found;
}
@@ -987,12 +987,16 @@ static GWorkGroup *g_work_queue_ensure_group_exists(GWorkQueue *queue, wgroup_id
wgroup_id_t g_work_queue_define_work_group(GWorkQueue *queue)
{
wgroup_id_t result; /* Valeur à retourner */
+ bool created; /* Bilan d'une tentative */
g_mutex_lock(&queue->mutex);
- result = ++queue->generator;
-
- g_work_queue_ensure_group_exists(queue, result);
+ do
+ {
+ result = queue->generator++;
+ created = g_work_queue_ensure_group_exists(queue, result);
+ }
+ while (!created);
g_mutex_unlock(&queue->mutex);
@@ -1072,13 +1076,8 @@ void g_work_queue_schedule_work(GWorkQueue *queue, GDelayedWork *work, wgroup_id
{
GWorkGroup *group; /* Groupe de travail à attendre*/
- g_mutex_lock(&queue->mutex);
-
- group = g_work_queue_ensure_group_exists(queue, id);
-
- g_object_ref(G_OBJECT(group));
-
- g_mutex_unlock(&queue->mutex);
+ group = g_work_queue_find_group_for_id(queue, id);
+ assert(group != NULL);
g_work_group_schedule(group, work);
@@ -1188,7 +1187,9 @@ void g_work_queue_wait_for_completion(GWorkQueue *queue, wgroup_id_t id)
/******************************************************************************
* *
-* Paramètres : queue = gestionnaire de l'ensemble des groupes de travail. *
+* Paramètres : queue = gestionnaire de l'ensemble des groupes de travail.*
+* gb_ids = identifiants de groupes globaux. *
+* gb_count = nombre de ces groupes globaux. *
* *
* Description : Attend que toutes les tâches de tout groupe soient traitées. *
* *
@@ -1198,36 +1199,29 @@ void g_work_queue_wait_for_completion(GWorkQueue *queue, wgroup_id_t id)
* *
******************************************************************************/
-void g_work_queue_wait_for_all_completions(GWorkQueue *queue)
+void g_work_queue_wait_for_all_completions(GWorkQueue *queue, const wgroup_id_t *gb_ids, size_t gb_count)
{
- GWorkGroup *def_group; /* Groupe de travail par défaut*/
+ size_t i; /* Boucle de parcours */
g_mutex_lock(&queue->mutex);
- /**
- * Récupération du groupe par défaut.
- */
-
- def_group = g_work_queue_ensure_group_exists(queue, DEFAULT_WORK_GROUP);
-
- g_object_ref(G_OBJECT(def_group));
-
wait_again:
/**
* Attente d'éventuels groupes isolés.
*/
- while (queue->groups_count > 1)
+ while (queue->groups_count > gb_count)
g_cond_wait(&queue->wait_all, &queue->mutex);
g_mutex_unlock(&queue->mutex);
/**
- * Attente du groupe principal.
+ * Attente des groupes principaux.
*/
- g_work_queue_wait_for_completion(queue, DEFAULT_WORK_GROUP);
+ for (i = 0; i < gb_count; i++)
+ g_work_queue_wait_for_completion(queue, gb_ids[i]);
/**
* Si le groupe par défaut a généré de nouveaux groupes, on recommence !
@@ -1235,13 +1229,11 @@ void g_work_queue_wait_for_all_completions(GWorkQueue *queue)
g_mutex_lock(&queue->mutex);
- if (queue->groups_count > 1)
+ if (queue->groups_count > gb_count)
goto wait_again;
g_mutex_unlock(&queue->mutex);
- g_object_unref(G_OBJECT(def_group));
-
}
diff --git a/src/glibext/delayed.h b/src/glibext/delayed.h
index 340a298..c22cc5a 100644
--- a/src/glibext/delayed.h
+++ b/src/glibext/delayed.h
@@ -82,9 +82,6 @@ typedef struct _GWorkQueueClass GWorkQueueClass;
/* Identifiant unique pour groupe de travail */
typedef unsigned long long wgroup_id_t;
-/* Groupe d'exécution par défaut */
-#define DEFAULT_WORK_GROUP 0
-
/* Indique le type défini pour le gestionnaire des travaux différés. */
GType g_work_queue_get_type(void);
@@ -108,7 +105,7 @@ bool g_work_queue_is_empty(GWorkQueue *, wgroup_id_t);
void g_work_queue_wait_for_completion(GWorkQueue *, wgroup_id_t);
/* Attend que toutes les tâches de tout groupe soient traitées. */
-void g_work_queue_wait_for_all_completions(GWorkQueue *);
+void g_work_queue_wait_for_all_completions(GWorkQueue *, const wgroup_id_t *, size_t);
/* Etudie le besoin d'attendre d'avantage de prochaines tâches. */