From f251814cf0fd10a767972530c119f8f109613c48 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 22 Jan 2019 19:36:15 +0100
Subject: Fixed run sizes of parallel jobs.

---
 plugins/dex/pool.c                 | 20 +++++---------------
 plugins/dwarf/info.c               |  4 +---
 plugins/elf/strings.c              |  4 +---
 plugins/elf/symbols.c              |  8 ++------
 plugins/lnxsyscalls/core.c         |  4 +---
 src/analysis/disass/area.c         | 18 ++++++------------
 src/analysis/disass/disassembler.c | 10 +++-------
 src/core/nproc.h                   | 17 +++++++++++++++++
 src/glibext/gwidthtracker.c        |  4 +---
 9 files changed, 37 insertions(+), 52 deletions(-)

diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c
index d95f519..fb710f3 100644
--- a/plugins/dex/pool.c
+++ b/plugins/dex/pool.c
@@ -77,9 +77,7 @@ bool load_all_dex_string_symbols(GDexFormat *format, wgroup_id_t gid, GtkStatusS
 
     /* Lancement des chargements */
 
-    runs_count = get_max_online_threads();
-
-    run_size = count / runs_count;
+    run_size = compute_run_size(count, &runs_count);
 
     queue = get_work_queue();
 
@@ -288,9 +286,7 @@ bool load_all_dex_types(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *sta
 
     /* Lancement des chargements */
 
-    runs_count = get_max_online_threads();
-
-    run_size = count / runs_count;
+    run_size = compute_run_size(count, &runs_count);
 
     queue = get_work_queue();
 
@@ -447,9 +443,7 @@ bool load_all_dex_fields(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *st
 
     /* Lancement des chargements */
 
-    runs_count = get_max_online_threads();
-
-    run_size = count / runs_count;
+    run_size = compute_run_size(count, &runs_count);
 
     queue = get_work_queue();
 
@@ -758,9 +752,7 @@ bool load_all_dex_methods(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *s
 
     /* Lancement des chargements */
 
-    runs_count = get_max_online_threads();
-
-    run_size = format->header.method_ids_size / runs_count;
+    run_size = compute_run_size(format->header.method_ids_size, &runs_count);
 
     queue = get_work_queue();
 
@@ -898,9 +890,7 @@ bool load_all_dex_classes(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *s
 
     /* Lancement des chargements */
 
-    runs_count = get_max_online_threads();
-
-    run_size = format->header.class_defs_size / runs_count;
+    run_size = compute_run_size(format->header.class_defs_size, &runs_count);
 
     queue = get_work_queue();
 
diff --git a/plugins/dwarf/info.c b/plugins/dwarf/info.c
index 7a2be44..b0d853c 100644
--- a/plugins/dwarf/info.c
+++ b/plugins/dwarf/info.c
@@ -149,9 +149,7 @@ bool load_dwarf_debug_information(GDwarfFormat *format, wgroup_id_t gid, GtkStat
 
         /* Lancement des travaux */
 
-        runs_count = get_max_online_threads();
-
-        run_size = count / runs_count;
+        run_size = compute_run_size(count, &runs_count);
 
         queue = get_work_queue();
 
diff --git a/plugins/elf/strings.c b/plugins/elf/strings.c
index 7dd644e..f6be4a8 100644
--- a/plugins/elf/strings.c
+++ b/plugins/elf/strings.c
@@ -206,9 +206,7 @@ static bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size,
     {
         final = start + size;
 
-        runs_count = get_max_online_threads();
-
-        run_size = size / runs_count;
+        run_size = compute_run_size(size, &runs_count);
 
         gtk_status_stack_extend_activity(status, msg, size);
 
diff --git a/plugins/elf/symbols.c b/plugins/elf/symbols.c
index 08d9377..b6f05f6 100644
--- a/plugins/elf/symbols.c
+++ b/plugins/elf/symbols.c
@@ -601,9 +601,7 @@ static void add_all_elf_symbols(GElfFormat *format, phys_t sym_start, size_t cou
 
     sym_size = ELF_SIZEOF_SYM(format);
 
-    runs_count = get_max_online_threads();
-
-    run_size = count / runs_count;
+    run_size = compute_run_size(count, &runs_count);
 
     gtk_status_stack_extend_activity(status, msg, count);
 
@@ -1017,9 +1015,7 @@ static bool load_elf_relocations(GElfFormat *format, const elf_phdr *dynamic, el
 
     queue = get_work_queue();
 
-    runs_count = get_max_online_threads();
-
-    run_size = length / runs_count;
+    run_size = compute_run_size(length, &runs_count);
 
     loadings = (GElfLoading **)malloc(runs_count * sizeof(GElfLoading *));
 
diff --git a/plugins/lnxsyscalls/core.c b/plugins/lnxsyscalls/core.c
index cd9fa0e..afc890b 100644
--- a/plugins/lnxsyscalls/core.c
+++ b/plugins/lnxsyscalls/core.c
@@ -128,9 +128,7 @@ G_MODULE_EXPORT void process_binary_disassembly(const GPluginModule *plugin, Plu
 
     sym_count = g_binary_format_count_symbols(format);
 
-    runs_count = get_max_online_threads();
-
-    run_size = sym_count / runs_count;
+    run_size = compute_run_size(sym_count, &runs_count);
 
     id = gtk_status_stack_add_activity(status, _("Looking for Linux syscalls..."), sym_count);
 
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 0a82b99..84bf8a4 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -1949,8 +1949,8 @@ mem_area *collect_memory_areas(wgroup_id_t gid, GtkStatusStack *status, GLoadedB
 {
     mem_area *result;                       /* Liste finale à retourner    */
     guint runs_count;                       /* Qté d'exécutions parallèles */
-    GAreaCollector **collectors;            /* Collecteurs à suivre        */
     phys_t run_size;                        /* Volume réparti par exécution*/
+    GAreaCollector **collectors;            /* Collecteurs à suivre        */
     GWorkQueue *queue;                      /* Gestionnaire de différés    */
     activity_id_t id;                       /* Identifiant de progression  */
     GMutex *global;                         /* Atomicité sur zones multi.  */
@@ -1967,12 +1967,10 @@ mem_area *collect_memory_areas(wgroup_id_t gid, GtkStatusStack *status, GLoadedB
 
     /* Lancement des traitements */
 
-    runs_count = get_max_online_threads();
+    run_size = compute_run_size(length, &runs_count);
 
     collectors = (GAreaCollector **)calloc(runs_count, sizeof(GAreaCollector *));
 
-    run_size = length / runs_count;
-
     queue = get_work_queue();
 
     id = gtk_status_stack_add_activity(status, _("Computing memory areas to disassemble"), length);
@@ -2133,8 +2131,8 @@ void populate_fresh_memory_areas(wgroup_id_t gid, GtkStatusStack *status, mem_ar
 {
     size_t icount;                          /* Quantité d'instructions     */
     guint runs_count;                       /* Qté d'exécutions parallèles */
-    GAreaCollector **collectors;            /* Collecteurs à suivre        */
     phys_t run_size;                        /* Volume réparti par exécution*/
+    GAreaCollector **collectors;            /* Collecteurs à suivre        */
     GWorkQueue *queue;                      /* Gestionnaire de différés    */
     activity_id_t id;                       /* Identifiant de progression  */
     guint i;                                /* Boucle de parcours          */
@@ -2145,12 +2143,10 @@ void populate_fresh_memory_areas(wgroup_id_t gid, GtkStatusStack *status, mem_ar
 
     icount = _g_preload_info_count_instructions(info);
 
-    runs_count = get_max_online_threads();
+    run_size = compute_run_size(icount, &runs_count);
 
     collectors = (GAreaCollector **)calloc(runs_count, sizeof(GAreaCollector *));
 
-    run_size = icount / runs_count;
-
     queue = get_work_queue();
 
     id = gtk_status_stack_add_activity(status, _("Inserting all preloaded instructions"), icount);
@@ -2410,8 +2406,8 @@ GArchInstruction **collect_disassembled_instructions(wgroup_id_t gid, GtkStatusS
     GArchInstruction **result;              /* Liste finale à retourner    */
     GMutex *global;                         /* Atomicité sur zones multi.  */
     guint runs_count;                       /* Qté d'exécutions parallèles */
-    GAreaCollector **collectors;            /* Collecteurs à suivre        */
     size_t run_size;                        /* Volume réparti par exécution*/
+    GAreaCollector **collectors;            /* Collecteurs à suivre        */
     GWorkQueue *queue;                      /* Gestionnaire de différés    */
     activity_id_t id;                       /* Identifiant de progression  */
     guint i;                                /* Boucle de parcours          */
@@ -2430,12 +2426,10 @@ GArchInstruction **collect_disassembled_instructions(wgroup_id_t gid, GtkStatusS
 
     /* Lancement des traitements */
 
-    runs_count = get_max_online_threads();
+    run_size = compute_run_size(acount, &runs_count);
 
     collectors = (GAreaCollector **)calloc(runs_count, sizeof(GAreaCollector *));
 
-    run_size = acount / runs_count;
-
     queue = get_work_queue();
 
     id = gtk_status_stack_add_activity(status, _("Collecting all disassembled instructions"), acount);
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index d73130c..e548fcd 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -76,8 +76,8 @@ static void compute_disassembly(GLoadedBinary *, GProcContext *, wgroup_id_t, Gt
 
 static void process_all_instructions(wgroup_id_t gid, GtkStatusStack *status, const char *msg, ins_fallback_cb fallback, GArchProcessor *proc, GProcContext *ctx, GExeFormat *format)
 {
-    guint runs_count;                       /* Qté d'exécutions parallèles */
     size_t ins_count;                       /* Quantité d'instructions     */
+    guint runs_count;                       /* Qté d'exécutions parallèles */
     size_t run_size;                        /* Volume réparti par exécution*/
     GWorkQueue *queue;                      /* Gestionnaire de différés    */
     activity_id_t id;                       /* Identifiant de progression  */
@@ -86,15 +86,13 @@ static void process_all_instructions(wgroup_id_t gid, GtkStatusStack *status, co
     size_t end;                             /* Fin d'un bloc de traitement */
     GInstructionsStudy *study;              /* Tâche d'étude à programmer  */
 
-    runs_count = get_max_online_threads();
-
     g_arch_processor_lock(proc);
 
     ins_count = g_arch_processor_count_instructions(proc);
 
     g_arch_processor_unlock(proc);
 
-    run_size = ins_count / runs_count;
+    run_size = compute_run_size(ins_count, &runs_count);
 
     queue = get_work_queue();
 
@@ -160,9 +158,7 @@ static void process_all_routines(GLoadedBinary *binary, wgroup_id_t gid, GtkStat
 
     sym_count = g_binary_format_count_symbols(format);
 
-    runs_count = get_max_online_threads();
-
-    run_size = sym_count / runs_count;
+    run_size = compute_run_size(sym_count, &runs_count);
 
     queue = get_work_queue();
 
diff --git a/src/core/nproc.h b/src/core/nproc.h
index 4a175b9..87cab23 100644
--- a/src/core/nproc.h
+++ b/src/core/nproc.h
@@ -33,5 +33,22 @@
 guint get_max_online_threads(void);
 
 
+/**
+ * Calcul de tranches de travaux, avec prise en compte des cas particuliers.
+ */
+#define compute_run_size(qty, cpus)                 \
+    ({                                              \
+        if (qty == 0)                               \
+            *(cpus) = 0;                            \
+        else                                        \
+        {                                           \
+            *(cpus) = get_max_online_threads();     \
+            if (qty < *(cpus))                      \
+                *(cpus) = qty;                      \
+        }                                           \
+        *(cpus) > 0 ? qty / *(cpus) : 0;            \
+    })
+
+
 
 #endif  /* _CORE_NPROC_H */
diff --git a/src/glibext/gwidthtracker.c b/src/glibext/gwidthtracker.c
index e116a85..50b99eb 100644
--- a/src/glibext/gwidthtracker.c
+++ b/src/glibext/gwidthtracker.c
@@ -1000,12 +1000,10 @@ void g_width_tracker_build_initial_cache(GWidthTracker *tracker, wgroup_id_t gid
 
     /* Lancement des traitements */
 
-    runs_count = get_max_online_threads();
+    run_size = compute_run_size(tracker->count, &runs_count);
 
     updates = (GWidthUpdate **)calloc(runs_count, sizeof(GWidthUpdate *));
 
-    run_size = tracker->count / runs_count;
-
     queue = get_work_queue();
 
     id = gtk_status_stack_add_activity(status, _("Computing width of all lines for rendering"), tracker->count);
-- 
cgit v0.11.2-87-g4458