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/instruction.c | |
parent | 2c70e3332b43bdcbe215081b697395d254418e48 (diff) |
Optimized access to instruction sources and destinations.
Diffstat (limited to 'src/arch/instruction.c')
-rw-r--r-- | src/arch/instruction.c | 204 |
1 files changed, 75 insertions, 129 deletions
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; |