diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-10-28 22:26:53 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-10-28 22:26:53 (GMT) |
commit | 8c71b36d401b2473342daddcb9b7eb4b83ba3295 (patch) | |
tree | 13515f99f3e01fc2d1701189e500fa69763da7f9 /src/arch | |
parent | 2c70e3332b43bdcbe215081b697395d254418e48 (diff) |
Optimized access to instruction sources and destinations.
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/instruction-int.h | 15 | ||||
-rw-r--r-- | src/arch/instruction.c | 204 | ||||
-rw-r--r-- | src/arch/instruction.h | 37 |
3 files changed, 100 insertions, 156 deletions
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index c393b5f..6c9da03 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -70,20 +70,13 @@ struct _GArchInstruction GArchOperand **operands; /* Liste des opérandes */ size_t operands_count; /* Nbre. d'opérandes utilisées */ - GArchInstruction **from; /* Origines des références */ - InstructionLinkType *from_types; /* Type des liens de dest. */ + instr_link_t *from; /* Origines des références */ size_t from_count; /* Nombre de ces origines */ - GRWLock from_access; /* Verrou de protection */ -#ifndef NDEBUG - gint hold_from_access; /* Suivi des verrouillages */ -#endif - - GArchInstruction **to; /* Eventuelles lignes visées */ - InstructionLinkType *to_types; /* Type des liens de dest. */ + instr_link_t *to; /* Instructions visées */ size_t to_count; /* Nombre de ces destinations */ - GRWLock to_access; /* Verrou de protection */ + GRWLock link_access; /* Verrou de protection */ #ifndef NDEBUG - gint hold_to_access; /* Suivi des verrouillages */ + gint hold_link_access; /* Suivi des verrouillages */ #endif //get_instruction_rw_regs_fc get_rw_regs; /* Liste des registres liés */ diff --git a/src/arch/instruction.c b/src/arch/instruction.c index fa631ac..b57b49d 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -107,11 +107,10 @@ static void g_arch_instruction_init(GArchInstruction *instr) instr->max_displayed_len = VMPA_NO_PHYSICAL; - g_rw_lock_init(&instr->from_access); - g_atomic_int_set(&instr->hold_from_access, 0); - - g_rw_lock_init(&instr->to_access); - g_atomic_int_set(&instr->hold_to_access, 0); + g_rw_lock_init(&instr->link_access); +#ifndef NDEBUG + g_atomic_int_set(&instr->hold_link_access, 0); +#endif } @@ -149,8 +148,7 @@ static void g_arch_instruction_dispose(GArchInstruction *instr) static void g_arch_instruction_finalize(GArchInstruction *instr) { - g_rw_lock_clear(&instr->from_access); - g_rw_lock_clear(&instr->to_access); + g_rw_lock_clear(&instr->link_access); G_OBJECT_CLASS(g_arch_instruction_parent_class)->finalize(G_OBJECT(instr)); @@ -559,6 +557,46 @@ void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchReg /****************************************************************************** * * +* Paramètres : instr = instruction à mettre à jour. * +* write = précise le type d'accès prévu (lecture/écriture). * +* lock = indique le sens du verrouillage à mener. * +* * +* Description : Met à disposition un encadrement des accès aux liens. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_arch_instruction_lock_unlock_links(GArchInstruction *instr, bool write, bool lock) +{ +#ifndef NDEBUG + if (!lock) + g_atomic_int_dec_and_test(&instr->hold_link_access); +#endif + + if (write) + { + if (lock) g_rw_lock_writer_lock(&instr->link_access); + else g_rw_lock_writer_unlock(&instr->link_access); + } + else + { + if (lock) g_rw_lock_reader_lock(&instr->link_access); + else g_rw_lock_reader_unlock(&instr->link_access); + } + +#ifndef NDEBUG + if (lock) + g_atomic_int_inc(&instr->hold_link_access); +#endif + +} + + +/****************************************************************************** +* * * Paramètres : instr = instruction dont les informations sont à consulter. * * dest = ligne visée par la liaison (côté destination). * * type = type de lien à construire. * @@ -575,6 +613,7 @@ void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchReg void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *dest, InstructionLinkType type) { size_t count; /* Raccourci pour la lecture */ + instr_link_t *new; /* Nouveau lien à définir */ /* Côté destination */ @@ -582,13 +621,12 @@ void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *des count = ++dest->from_count; - dest->from = (GArchInstruction **)realloc(dest->from, - count * sizeof(GArchInstruction *)); - dest->from_types = (InstructionLinkType *)realloc(dest->from_types, - count * sizeof(InstructionLinkType)); + dest->from = (instr_link_t *)realloc(dest->from, count * sizeof(instr_link_t)); + + new = &dest->from[count - 1]; - dest->from[count - 1] = instr; - dest->from_types[count - 1] = type; + new->linked = instr; + new->type = type; g_arch_instruction_wunlock_src(dest); @@ -598,13 +636,12 @@ void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *des count = ++instr->to_count; - instr->to = (GArchInstruction **)realloc(instr->to, - count * sizeof(GArchInstruction *)); - instr->to_types = (InstructionLinkType *)realloc(instr->to_types, - count * sizeof(InstructionLinkType)); + instr->to = (instr_link_t *)realloc(instr->to, count * sizeof(instr_link_t)); + + new = &instr->to[count - 1]; - instr->to[count - 1] = dest; - instr->to_types[count - 1] = type; + new->linked = dest; + new->type = type; g_arch_instruction_wunlock_dest(instr); @@ -636,7 +673,7 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d result = false; - assert(g_atomic_int_get(&instr->hold_to_access) > 0); + assert(g_atomic_int_get(&instr->hold_link_access) > 0); g_arch_instruction_wlock_src(dest); @@ -645,7 +682,7 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d count = dest->from_count; for (i = 0; i < count; i++) - if (dest->from[i] == instr && dest->from_types[i] == old) + if (dest->from[i].linked == instr && dest->from[i].type == old) break; if (i == count) @@ -658,7 +695,7 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d count = instr->to_count; for (i = 0; i < count; i++) - if (instr->to[i] == dest && instr->to_types[i] == old) + if (instr->to[i].linked == dest && instr->to[i].type == old) break; if (i == count) @@ -668,9 +705,9 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d /* Si les deux extrémités sont raccord... */ - dest->from_types[from_idx] = new; + dest->from[from_idx].type = new; - instr->to_types[to_idx] = new; + instr->to[to_idx].type = new; result = true; @@ -680,49 +717,6 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d return result; - - /* TODO : si les informations complémentaires restent en place, compléter ! */ - -} - - -/****************************************************************************** -* * -* Paramètres : collec = collection à mettre à jour. * -* write = précise le type d'accès prévu (lecture/écriture). * -* lock = indique le sens du verrouillage à mener. * -* * -* Description : Met à disposition un encadrement des accès aux sources. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_arch_instruction_lock_unlock_sources(GArchInstruction *instr, bool write, bool lock) -{ -#ifndef NDEBUG - if (!lock) - g_atomic_int_dec_and_test(&instr->hold_from_access); -#endif - - if (write) - { - if (lock) g_rw_lock_writer_lock(&instr->from_access); - else g_rw_lock_writer_unlock(&instr->from_access); - } - else - { - if (lock) g_rw_lock_reader_lock(&instr->from_access); - else g_rw_lock_reader_unlock(&instr->from_access); - } - -#ifndef NDEBUG - if (lock) - g_atomic_int_inc(&instr->hold_from_access); -#endif - } @@ -740,7 +734,7 @@ void g_arch_instruction_lock_unlock_sources(GArchInstruction *instr, bool write, bool g_arch_instruction_has_sources(const GArchInstruction *instr) { - assert(g_atomic_int_get(&instr->hold_from_access) > 0); + assert(g_atomic_int_get(&instr->hold_link_access) > 0); return (instr->from_count > 0); @@ -749,9 +743,8 @@ bool g_arch_instruction_has_sources(const GArchInstruction *instr) /****************************************************************************** * * -* Paramètres : instr = instruction dont les informations sont à consulter. * -* srcs = liste des instructions d'origine. [OUT] * -* types = liste des types de liens présents. [OUT] * +* Paramètres : instr = instruction dont les informations sont à consulter.* +* sources = liste des liens aux instructions d'origine. [OUT] * * * * Description : Fournit les origines d'une instruction donnée. * * * @@ -761,15 +754,12 @@ bool g_arch_instruction_has_sources(const GArchInstruction *instr) * * ******************************************************************************/ -size_t g_arch_instruction_get_sources(const GArchInstruction *instr, GArchInstruction ***srcs, InstructionLinkType **types) +size_t g_arch_instruction_get_sources(const GArchInstruction *instr, instr_link_t **sources) { - assert(g_atomic_int_get(&instr->hold_from_access) > 0); - - if (srcs != NULL) - *srcs = instr->from; + assert(g_atomic_int_get(&instr->hold_link_access) > 0); - if (types != NULL) - *types = instr->from_types; + if (sources != NULL) + *sources = instr->from; return instr->from_count; @@ -778,46 +768,6 @@ size_t g_arch_instruction_get_sources(const GArchInstruction *instr, GArchInstru /****************************************************************************** * * -* Paramètres : collec = collection à mettre à jour. * -* write = précise le type d'accès prévu (lecture/écriture). * -* lock = indique le sens du verrouillage à mener. * -* * -* Description : Met à disposition un encadrement des accès aux destinations. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_arch_instruction_lock_unlock_destinations(GArchInstruction *instr, bool write, bool lock) -{ -#ifndef NDEBUG - if (!lock) - g_atomic_int_dec_and_test(&instr->hold_to_access); -#endif - - if (write) - { - if (lock) g_rw_lock_writer_lock(&instr->to_access); - else g_rw_lock_writer_unlock(&instr->to_access); - } - else - { - if (lock) g_rw_lock_reader_lock(&instr->to_access); - else g_rw_lock_reader_unlock(&instr->to_access); - } - -#ifndef NDEBUG - if (lock) - g_atomic_int_inc(&instr->hold_to_access); -#endif - -} - - -/****************************************************************************** -* * * Paramètres : instr = instruction dont les informations sont à consulter. * * * * Description : Indique si l'instruction a une suite autre que la suivante. * @@ -830,7 +780,7 @@ void g_arch_instruction_lock_unlock_destinations(GArchInstruction *instr, bool w bool g_arch_instruction_has_destinations(const GArchInstruction *instr) { - assert(g_atomic_int_get(&instr->hold_to_access) > 0); + assert(g_atomic_int_get(&instr->hold_link_access) > 0); return (instr->to_count > 0); @@ -840,8 +790,7 @@ bool g_arch_instruction_has_destinations(const GArchInstruction *instr) /****************************************************************************** * * * Paramètres : instr = instruction dont les informations sont à consulter. * -* dests = liste des instructions de destination. [OUT] * -* types = liste des types de liens présents. [OUT] * +* dests = liste de liens aux instructions de destination. [OUT]* * * * Description : Fournit les destinations d'une instruction donnée. * * * @@ -851,16 +800,13 @@ bool g_arch_instruction_has_destinations(const GArchInstruction *instr) * * ******************************************************************************/ -size_t g_arch_instruction_get_destinations(const GArchInstruction *instr, GArchInstruction ***dests, InstructionLinkType **types) +size_t g_arch_instruction_get_destinations(const GArchInstruction *instr, instr_link_t **dests) { - assert(g_atomic_int_get(&instr->hold_to_access) > 0); + assert(g_atomic_int_get(&instr->hold_link_access) > 0); if (dests != NULL) *dests = instr->to; - if (types != NULL) - *types = instr->to_types; - return instr->to_count; } @@ -886,11 +832,11 @@ GArchInstruction *g_arch_instruction_get_given_destination(const GArchInstructio result = NULL; - assert(g_atomic_int_get(&instr->hold_to_access) > 0); + assert(g_atomic_int_get(&instr->hold_link_access) > 0); for (i = 0; i < instr->to_count && result == NULL; i++) - if (instr->to_types[i] == type) - result = instr->to[i]; + if (instr->to[i].type == type) + result = instr->to[i].linked; return result; diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 00e64ab..fed88a3 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -174,6 +174,17 @@ typedef enum _InstructionLinkType } InstructionLinkType; +/* Déscription d'une liaison entre deux instructions */ +typedef struct _instr_link_t +{ + GArchInstruction *linked; /* Autre instruction liée */ + InstructionLinkType type; /* Type de liaison */ + +} instr_link_t; + + +/* Met à disposition un encadrement des accès aux liens. */ +void g_arch_instruction_lock_unlock_links(GArchInstruction *, bool, bool); /* Etablit un lien entre deux instructions. */ void g_arch_instruction_link_with(GArchInstruction *, GArchInstruction *, InstructionLinkType); @@ -181,35 +192,29 @@ void g_arch_instruction_link_with(GArchInstruction *, GArchInstruction *, Instru /* Change la nature d'un lien entre deux instructions. */ bool g_arch_instruction_change_link(GArchInstruction *, GArchInstruction *, InstructionLinkType, InstructionLinkType); -/* Met à disposition un encadrement des accès aux sources. */ -void g_arch_instruction_lock_unlock_sources(GArchInstruction *, bool, bool); - -#define g_arch_instruction_wlock_src(ins) g_arch_instruction_lock_unlock_sources(ins, true, true) -#define g_arch_instruction_wunlock_src(ins) g_arch_instruction_lock_unlock_sources(ins, true, false) +#define g_arch_instruction_wlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, true) +#define g_arch_instruction_wunlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, false) -#define g_arch_instruction_rlock_src(ins) g_arch_instruction_lock_unlock_sources(ins, false, true) -#define g_arch_instruction_runlock_src(ins) g_arch_instruction_lock_unlock_sources(ins, false, false) +#define g_arch_instruction_rlock_src(ins) g_arch_instruction_lock_unlock_links(ins, false, true) +#define g_arch_instruction_runlock_src(ins) g_arch_instruction_lock_unlock_links(ins, false, false) /* Indique si l'instruction a une ou plusieurs origines. */ bool g_arch_instruction_has_sources(const GArchInstruction *); /* Fournit les origines d'une instruction donnée. */ -size_t g_arch_instruction_get_sources(const GArchInstruction *, GArchInstruction ***, InstructionLinkType **); - -/* Met à disposition un encadrement des accès aux destinations. */ -void g_arch_instruction_lock_unlock_destinations(GArchInstruction *, bool, bool); +size_t g_arch_instruction_get_sources(const GArchInstruction *, instr_link_t **); -#define g_arch_instruction_wlock_dest(ins) g_arch_instruction_lock_unlock_destinations(ins, true, true) -#define g_arch_instruction_wunlock_dest(ins) g_arch_instruction_lock_unlock_destinations(ins, true, false) +#define g_arch_instruction_wlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, true, true) +#define g_arch_instruction_wunlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, true, false) -#define g_arch_instruction_rlock_dest(ins) g_arch_instruction_lock_unlock_destinations(ins, false, true) -#define g_arch_instruction_runlock_dest(ins) g_arch_instruction_lock_unlock_destinations(ins, false, false) +#define g_arch_instruction_rlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, true) +#define g_arch_instruction_runlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, false) /* Indique si l'instruction a une suite autre que la suivante. */ bool g_arch_instruction_has_destinations(const GArchInstruction *); /* Fournit les destinations d'une instruction donnée. */ -size_t g_arch_instruction_get_destinations(const GArchInstruction *, GArchInstruction ***, InstructionLinkType **); +size_t g_arch_instruction_get_destinations(const GArchInstruction *, instr_link_t **); /* Fournit la destination d'une instruction et d'un type donné. */ GArchInstruction *g_arch_instruction_get_given_destination(const GArchInstruction *, InstructionLinkType); |