diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-12-19 20:22:14 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-12-19 20:22:14 (GMT) |
commit | 5710f9d5be56b427ccfa48f6a730d70396817efe (patch) | |
tree | 4b694774ce446295ef5b01a7df28bd8160b97025 /src/analysis | |
parent | 8ff010a34762737016624a68f593d0e6736d4349 (diff) |
Fixed several bugs when processing concurrent delayed works.
Diffstat (limited to 'src/analysis')
-rw-r--r-- | src/analysis/disass/fetch.c | 88 |
1 files changed, 75 insertions, 13 deletions
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 5caf573..29d8923 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -309,7 +309,8 @@ static void g_delayed_fetching_process(GDelayedFetching *fetching, GtkExtStatusB /* Poursuit l'analyse à partir des points d'entrée découverts. */ static void follow_execution_flow_v2(GProcContext *, const GDelayedFetching *); - +/* Etudie le besoin d'attendre d'avantage de prochaines tâches. */ +static bool check_if_extra_wait_is_needed(GWorkQueue *, wgroup_id_t, GProcContext *); @@ -331,11 +332,14 @@ static void follow_execution_flow_v2(GProcContext *, const GDelayedFetching *); static void follow_execution_flow_v2(GProcContext *ctx, const GDelayedFetching *template) { GWorkQueue *queue; /* Gestionnaire de différés */ + gint *remaining_counter; /* Compteur à considérer */ virt_t virt; /* Adresse de départ dépilée */ GDelayedFetching *fetching; /* Récupération à mener */ queue = get_work_queue(); + remaining_counter = (gint *)g_object_get_data(G_OBJECT(ctx), "remaining_counter"); + while (g_proc_context_pop_drop_point(ctx, &virt)) { fetching = g_delayed_fetching_new(template, virt); @@ -351,6 +355,16 @@ static void follow_execution_flow_v2(GProcContext *ctx, const GDelayedFetching * g_work_queue_schedule_work(queue, G_DELAYED_WORK(fetching), template->gid); + /** + * Le décompte n'est réalisé qu'après la programmation de la tâche. + * Ainsi, lors de l'attente de la fin des traitements, on a la garantie + * de ne pas avoir de trou entre le dépilement des points et la programmation + * des tâches de traitement associées. + */ + + if (g_atomic_int_dec_and_test(remaining_counter)) + g_work_queue_wake_up_waiters(queue, template->gid); + } } @@ -358,6 +372,45 @@ static void follow_execution_flow_v2(GProcContext *ctx, const GDelayedFetching * /****************************************************************************** * * +* Paramètres : queue = gestionnaire de l'ensemble des groupes de travail. * +* id = identifiant d'un groupe de travail. * +* ctx = contexte de désass. avec une nouvelle entrée. * +* * +* Description : Etudie le besoin d'attendre d'avantage de prochaines tâches. * +* * +* Retour : true pour attendre d'avantage, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool check_if_extra_wait_is_needed(GWorkQueue *queue, wgroup_id_t id, GProcContext *ctx) +{ + bool result; /* Bilan à retourner */ + gint *remaining_counter; /* Compteur à considérer */ + + remaining_counter = (gint *)g_object_get_data(G_OBJECT(ctx), "remaining_counter"); + + result = (g_atomic_int_get(remaining_counter) > 0); + + return result; + +} + + + + + + + + + + + + + +/****************************************************************************** +* * * Paramètres : binary = représentation de binaire chargé. * * ctx = contexte offert en soutien à un désassemblage. * * areas = liste de zones contenant des données à traiter. * @@ -435,15 +488,9 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, wgroup GBinContent *content; /* Contenu binaire à manipuler */ phys_t length; /* Taille des données à lire */ GWorkQueue *queue; /* Gestionnaire de différés */ + gint remaining_counter; /* Quantité de points restants */ double done; /* Portion de travail accompli */ - - - - - - - /* Constitution du modèle de référence */ template.gid = gid; @@ -463,24 +510,33 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, wgroup /* Amorce des traitements */ - g_signal_connect(template.ctx, "drop-point-pushed", G_CALLBACK(follow_execution_flow_v2), &template); - queue = get_work_queue(); + g_atomic_int_set(&remaining_counter, 0); + + g_object_set_data(G_OBJECT(template.ctx), "remaining_counter", &remaining_counter); + + g_proc_context_attach_counter(template.ctx, &remaining_counter); + /** * Première phase de désassemblage : suivi des chemins tracés. */ + + g_work_queue_set_extra_wait_callback(queue, gid, + (wait_for_incoming_works_cb)check_if_extra_wait_is_needed, + template.ctx); + + g_signal_connect(template.ctx, "drop-point-pushed", G_CALLBACK(follow_execution_flow_v2), &template); + template.info = init_progessive_status(statusbar, _("Disassembling following the execution flow..."), 0, length); - + g_binary_format_setup_disassembling_context(format, template.ctx); g_work_queue_wait_for_completion(queue, gid); - printf("===================== DONE !\n"); - done = get_current_progessive_status(template.info); fini_progessive_status(template.info); @@ -495,6 +551,12 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, wgroup ensure_all_mem_areas_are_filled(template.areas, template.count, template.ctx, template.info); + g_work_queue_wait_for_completion(queue, gid); + + g_work_queue_set_extra_wait_callback(queue, gid, NULL, NULL); + + g_object_set_data(G_OBJECT(template.ctx), "remaining_counter", NULL); + fini_progessive_status(template.info); /** |