diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2017-03-30 17:20:58 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2017-03-30 17:20:58 (GMT) |
commit | dda68634391bea512a7861468fcf45f8292300bb (patch) | |
tree | c56c9b1c0bb4500973247eef12ccadaf4ebe346d /src/common | |
parent | b8d5a539b1e6837f7395598a3fa25ef69650e885 (diff) |
Discriminated between tests for set and unset ranges of bits.
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/bits.c | 234 | ||||
-rw-r--r-- | src/common/bits.h | 42 |
2 files changed, 81 insertions, 195 deletions
diff --git a/src/common/bits.c b/src/common/bits.c index d941e54..d4d5074 100644 --- a/src/common/bits.c +++ b/src/common/bits.c @@ -31,9 +31,6 @@ -/* ----------------------------- CHAMPS DE BITS SIMPLES ----------------------------- */ - - /* Champ de bits simple */ struct _bitfield_t { @@ -57,12 +54,10 @@ static bitfield_t *_create_bit_field_from(const bitfield_t *, bool, size_t); /* Crée une copie d'un champ de bits classique. */ static bitfield_t *_dup_bit_field(const bitfield_t *, size_t); +/* Détermine si un ensemble de bits est homogène dans un champ. */ +static bool test_state_in_bit_field(const bitfield_t *, size_t, size_t, bool); -/* ---------------------------------------------------------------------------------- */ -/* CHAMPS DE BITS SIMPLES */ -/* ---------------------------------------------------------------------------------- */ - /****************************************************************************** * * @@ -397,14 +392,14 @@ bool set_atomic_in_bit_field(bitfield_t *field, size_t first, size_t count) result = ((oldval & mask) == 0); - assert(test_in_bit_field(field, first, count)); + assert(test_all_in_bit_field(field, first, count)); } else { g_mutex_lock(&field->mutex); - result = !test_in_bit_field(field, first, count); + result = test_none_in_bit_field(field, first, count); if (result) set_in_bit_field(field, first, count); @@ -471,8 +466,7 @@ void or_bit_field(bitfield_t *dest, const bitfield_t *src) /****************************************************************************** * * * Paramètres : field = champ de bits à modifier. * -* first = indice du premier bit à traiter. * -* count = nombre de bits à marquer. * +* n = indice du bit à traiter. * * * * Description : Détermine si un bit est à 1 dans un champ de bits. * * * @@ -482,28 +476,18 @@ void or_bit_field(bitfield_t *dest, const bitfield_t *src) * * ******************************************************************************/ -bool test_in_bit_field(const bitfield_t *field, size_t first, size_t count) +bool test_in_bit_field(const bitfield_t *field, size_t n) { bool result; /* Valeur retrouvée à renvoyer */ - size_t last; /* Point d'arrêt de la boucle */ - size_t i; /* Boucle de parcours */ size_t index; /* Cellule de tableau visée */ size_t remaining; /* Nombre de bits restants */ - last = first + count; - - assert(last <= field->length); - - result = true; - - for (i = first; i < last && result; i++) - { - index = i / (sizeof(unsigned long) * 8); - remaining = i % (sizeof(unsigned long) * 8); + assert(n < field->length); - result = field->bits[index] & (1ul << remaining); + index = n / (sizeof(unsigned long) * 8); + remaining = n % (sizeof(unsigned long) * 8); - } + result = field->bits[index] & (1ul << remaining); return result; @@ -512,220 +496,150 @@ bool test_in_bit_field(const bitfield_t *field, size_t first, size_t count) /****************************************************************************** * * -* Paramètres : a = premier champ de bits à comparer. * -* b = second champ de bits à comparer. * +* Paramètres : field = champ de bits à modifier. * +* first = indice du premier bit à traiter. * +* count = nombre de bits à marquer. * +* state = état global à retrouver idéalement. * * * -* Description : Indique si deux champs de bits sont identiques ou non. * +* Description : Détermine si un ensemble de bits est homogène dans un champ. * * * -* Retour : true si les champs de bits sont égaux ou false sinon. * +* Retour : true si le bit correspondant est à l'état haut. * * * * Remarques : - * * * ******************************************************************************/ -bool is_bit_field_equal_to(const bitfield_t *a, const bitfield_t *b) +static bool test_state_in_bit_field(const bitfield_t *field, size_t first, size_t count, bool state) { - bool result; /* Résultat à retourner */ + size_t last; /* Point d'arrêt de la boucle */ size_t i; /* Boucle de parcours */ + size_t index; /* Cellule de tableau visée */ size_t remaining; /* Nombre de bits restants */ + bool current; /* Etat d'un bit donné */ - if (a->length != b->length) - return false; - - result = true; + assert(count > 0); - for (i = 0; i < (a->requested - 1) && result; i++) - result = (a->bits[i] == b->bits[i]); + last = first + count; - if (result) + for (i = first; i < last; i++) { - remaining = a->length % sizeof(unsigned long); - - if (remaining == 0) - result = (a->bits[i] == b->bits[i]); - - else - { - remaining = (1 << (remaining + 1)) - 1; + index = i / (sizeof(unsigned long) * 8); + remaining = i % (sizeof(unsigned long) * 8); - result = ((a->bits[i] & remaining) == (b->bits[i] & remaining)); + current = field->bits[index] & (1ul << remaining); - } + if (current != state) break; } - return result; - -} - - - - -unsigned long gfw(const bitfield_t *field) -{ - return field->bits[0]; + return (i == last); } -#if 0 - -/* ---------------------------------------------------------------------------------- */ -/* CHAMPS LIES À UNE ZONE MEMOIRE */ -/* ---------------------------------------------------------------------------------- */ - /****************************************************************************** * * -* Paramètres : range = espace mémoire à couvrir. * -* state = état initial de chaque des bits. * +* Paramètres : field = champ de bits à modifier. * +* first = indice du premier bit à traiter. * +* count = nombre de bits à marquer. * * * -* Description : Crée un champ de bits couvrant une zone mémoire. * +* Description : Détermine si un ensemble de bits est à 0 dans un champ. * * * -* Retour : Champ de bits mis en place. * +* Retour : true si le bit correspondant est à l'état haut. * * * * Remarques : - * * * ******************************************************************************/ -memfield_t *create_mem_field(const mrange_t *range, bool state) +bool test_none_in_bit_field(const bitfield_t *field, size_t first, size_t count) { - bitfield_t *result; /* Création à retourner */ - - result = _create_bit_field(get_mrange_length(range), state, sizeof(vmpa2t)); + bool result; /* Valeur retrouvée à renvoyer */ - copy_vmpa((vmpa2t *)result->tail, get_mrange_addr(range)); + result = test_state_in_bit_field(field, first, count, false); - return (memfield_t *)result; + return result; } /****************************************************************************** * * -* Paramètres : range = espace mémoire à couvrir. * +* Paramètres : field = champ de bits à modifier. * +* first = indice du premier bit à traiter. * +* count = nombre de bits à marquer. * * * -* Description : Crée une copie de champ de bits couvrant une zone mémoire. * +* Description : Détermine si un ensemble de bits est à 1 dans un champ. * * * -* Retour : Champ de bits mis en place. * +* Retour : true si le bit correspondant est à l'état haut. * * * * Remarques : - * * * ******************************************************************************/ -memfield_t *create_mem_field_from(const memfield_t *field) +bool test_all_in_bit_field(const bitfield_t *field, size_t first, size_t count) { - bitfield_t *result; /* Création à retourner */ - - result = _create_bit_field_from((bitfield_t *)field, false, sizeof(vmpa2t)); - - copy_vmpa((vmpa2t *)result->tail, (vmpa2t *)field->tail); - - return (memfield_t *)result; - -} - + bool result; /* Valeur retrouvée à renvoyer */ -/****************************************************************************** -* * -* Paramètres : field = champ de bits à effacer. * -* * -* Description : Supprime de la mémoire un champ de bits donné. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ + result = test_state_in_bit_field(field, first, count, true); -void delete_mem_field(memfield_t *field) -{ - delete_bit_field((bitfield_t *)field); + return result; } /****************************************************************************** * * -* Paramètres : field = champ de bits à dupliquer. * +* Paramètres : a = premier champ de bits à comparer. * +* b = second champ de bits à comparer. * * * -* Description : Crée une copie d'un champ de bits couvrant une zone mémoire. * +* Description : Indique si deux champs de bits sont identiques ou non. * * * -* Retour : Champ de bits mis en place. * +* Retour : true si les champs de bits sont égaux ou false sinon. * * * * Remarques : - * * * ******************************************************************************/ -memfield_t *dup_mem_field(const memfield_t *field) +bool is_bit_field_equal_to(const bitfield_t *a, const bitfield_t *b) { - bitfield_t *result; /* Création à retourner */ - - result = _dup_bit_field((bitfield_t *)field, sizeof(vmpa2t)); + bool result; /* Résultat à retourner */ + size_t i; /* Boucle de parcours */ + size_t remaining; /* Nombre de bits restants */ - copy_vmpa((vmpa2t *)result->tail, (vmpa2t *)field->tail); + if (a->length != b->length) + return false; - return (memfield_t *)result; + result = true; -} + for (i = 0; i < (a->requested - 1) && result; i++) + result = (a->bits[i] == b->bits[i]); + if (result) + { + remaining = a->length % sizeof(unsigned long); -/****************************************************************************** -* * -* Paramètres : field = champ de bits à modifier. * -* addr = emplacement en mémoire à traiter. * -* * -* Description : Bascule à 1 un bit d'un champ de bits. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ + if (remaining == 0) + result = (a->bits[i] == b->bits[i]); -void set_in_mem_field(memfield_t *field, const vmpa2t *addr) -{ - vmpa2t *start; /* Adresse de début */ - phys_t offset; /* Décallage de départ */ + else + { + remaining = (1 << (remaining + 1)) - 1; - start = (vmpa2t *)field->tail; + result = ((a->bits[i] & remaining) == (b->bits[i] & remaining)); - assert(cmp_vmpa(start, addr) <= 0); + } - offset = compute_vmpa_diff(start, addr); + } - set_in_bit_field((bitfield_t *)field, offset, 1); + return result; } -/****************************************************************************** -* * -* Paramètres : field = champ de bits à modifier. * -* addr = emplacement en mémoire à tester. * -* * -* Description : Détermine si un bit est à 1 dans un champ de bits. * -* * -* Retour : true si le bit correspondant est à l'état haut. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool test_in_mem_field(memfield_t *field, const vmpa2t *addr) -{ - bool result; /* Valeur retrouvée à renvoyer */ - vmpa2t *start; /* Adresse de début */ - phys_t offset; /* Décallage de départ */ - - start = (vmpa2t *)field->tail; - - assert(cmp_vmpa(start, addr) <= 0); - offset = compute_vmpa_diff(start, addr); - result = test_in_bit_field((bitfield_t *)field, offset, 1); - - return result; +unsigned long gfw(const bitfield_t *field) +{ + return field->bits[0]; } -#endif diff --git a/src/common/bits.h b/src/common/bits.h index 1396789..4a2937f 100644 --- a/src/common/bits.h +++ b/src/common/bits.h @@ -29,9 +29,6 @@ -/* ----------------------------- CHAMPS DE BITS SIMPLES ----------------------------- */ - - /* Champ de bits simple */ typedef struct _bitfield_t bitfield_t; @@ -70,7 +67,13 @@ void and_bit_field(bitfield_t *, const bitfield_t *); void or_bit_field(bitfield_t *, const bitfield_t *); /* Détermine si un bit est à 1 dans un champ de bits. */ -bool test_in_bit_field(const bitfield_t *, size_t, size_t); +bool test_in_bit_field(const bitfield_t *, size_t); + +/* Détermine si un ensemble de bits est à 0 dans un champ. */ +bool test_none_in_bit_field(const bitfield_t *, size_t, size_t); + +/* Détermine si un ensemble de bits est à 1 dans un champ. */ +bool test_all_in_bit_field(const bitfield_t *, size_t, size_t); /* Indique si deux champs de bits sont identiques ou non. */ bool is_bit_field_equal_to(const bitfield_t *, const bitfield_t *); @@ -80,37 +83,6 @@ bool is_bit_field_equal_to(const bitfield_t *, const bitfield_t *); unsigned long gfw(const bitfield_t *); -#if 0 -/* ------------------------- CHAMPS LIES À UNE ZONE MEMOIRE ------------------------- */ - - -/* Champ de bits couvrant une mémoire */ -typedef struct _bitfield_t memfield_t; - - -/* Crée un champ de bits couvrant une zone mémoire. */ -memfield_t *create_mem_field(const mrange_t *, bool); - -/* Crée une copie de champ de bits couvrant une zone mémoire. */ -memfield_t *create_mem_field_from(const memfield_t *); - -/* Supprime de la mémoire un champ de bits donné. */ -void delete_mem_field(memfield_t *); - -/* Crée une copie d'un champ de bits couvrant une zone mémoire. */ -memfield_t *dup_mem_field(const memfield_t *); - -/* Bascule à 1 un bit d'un champ de bits. */ -void set_in_mem_field(memfield_t *, const vmpa2t *); - -/* Détermine si un bit est à 1 dans un champ de bits. */ -bool test_in_mem_field(memfield_t *, const vmpa2t *); - - - -#define set_atomic_in_mem_field(f, range) false - -#endif #endif /* _COMMON_BITS_H */ |