diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/bits.c | 68 | ||||
| -rw-r--r-- | src/common/bits.h | 9 | 
2 files changed, 77 insertions, 0 deletions
diff --git a/src/common/bits.c b/src/common/bits.c index d451100..b08dcb4 100644 --- a/src/common/bits.c +++ b/src/common/bits.c @@ -25,6 +25,7 @@  #include <assert.h> +#include <glib.h>  #include <malloc.h>  #include <string.h> @@ -41,6 +42,7 @@ struct _bitfield_t      void *tail;                             /* Limite du tableau de bits   */ +    GMutex mutex;                           /* Garantie d'atomicité        */      unsigned long bits[0];                  /* Mémoire d'accès associée    */  }; @@ -94,6 +96,8 @@ static bitfield_t *_create_bit_field(size_t length, bool state, size_t extra)      result->tail = ((char *)result) + base; +    g_mutex_init(&result->mutex); +      if (state)          set_all_in_bit_field(result);      else @@ -177,6 +181,8 @@ bitfield_t *create_bit_field_from(const bitfield_t *field)  void delete_bit_field(bitfield_t *field)  { +    g_mutex_clear(&field->mutex); +      free(field);  } @@ -330,6 +336,68 @@ void set_in_bit_field(bitfield_t *field, size_t first, size_t count)  /******************************************************************************  *                                                                             * +*  Paramètres  : field = champ de bits à modifier.                            * +*                first = indice du premier bit à traiter.                     * +*                count = nombre de bits à marquer.                            * +*                                                                             * +*  Description : Bascule à 1 de façon atomique une partie d'un champ de bits. * +*                                                                             * +*  Retour      : true si la zone traitée était entièrement vierge.            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool set_atomic_in_bit_field(bitfield_t *field, size_t first, size_t count) +{ +    bool result;                            /* Bilan à retourner           */ +    size_t start;                           /* Mot de départ               */ +    size_t end;                             /* Mot d'arrivée               */ +    size_t remaining;                       /* Nombre de bits restants     */ +    unsigned long oldval;                   /* Ancienne valeur présente    */ +    unsigned long mask;                     /* Nouvelle valeur à insérer   */ + +    start = first / (sizeof(unsigned long) * 8); +    end = (first + count - 1) / (sizeof(unsigned long) * 8); + +#if 0 //sizeof(gsize) != sizeof(unsigned long) +#   warning "Can not perform atomic operations on bit fields!" +#else +    if (start == end) +    { +        remaining = first % (sizeof(unsigned long) * 8); + +        assert(count > 0); + +        mask = (1 << count) - 1; +        mask <<= remaining; + +        oldval = g_atomic_pointer_or(&field->bits[start], mask); + +        result = ((oldval & mask) == 0); + +    } +    else +#endif +    { +        g_mutex_lock(&field->mutex); + +        result = !test_in_bit_field(field, first, count); + +        if (result) +            set_in_bit_field(field, first, count); + +        g_mutex_unlock(&field->mutex); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : dest = champ de bits à modifier.                             *  *                src  = champ de bits à utiliser pour l'opération.            *  *                                                                             * diff --git a/src/common/bits.h b/src/common/bits.h index 0e8ef65..074aac4 100644 --- a/src/common/bits.h +++ b/src/common/bits.h @@ -60,6 +60,9 @@ void set_all_in_bit_field(bitfield_t *);  /* Bascule à 1 une partie d'un champ de bits. */  void set_in_bit_field(bitfield_t *, size_t, size_t); +/* Bascule à 1 de façon atomique une partie d'un champ de bits. */ +bool set_atomic_in_bit_field(bitfield_t *, size_t, size_t); +  /* Réalise une opération ET logique entre deux champs de bits. */  void and_bit_field(bitfield_t *, const bitfield_t *); @@ -74,6 +77,7 @@ bool is_bit_field_equal_to(const bitfield_t *, const bitfield_t *); +  unsigned long gfw(const bitfield_t *); @@ -104,4 +108,9 @@ bool test_in_mem_field(memfield_t *, const vmpa2t *); +#define set_atomic_in_mem_field(f, range) false + + + +  #endif  /* _COMMON_BITS_H */  | 
