diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-11-26 23:30:01 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-11-26 23:30:01 (GMT) |
commit | 6b1a70c16f83a926f7b1f1fb2af5d6a2e017737b (patch) | |
tree | 8ffb0b3d8f3063c612f8cebe4f00a65f8b029a52 /src/common/bits.c | |
parent | a93a5dca1a7292b7e61ae09b74f3252e04b73488 (diff) |
Used several threads without lock to disassemble binary code.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@610 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/common/bits.c')
-rw-r--r-- | src/common/bits.c | 68 |
1 files changed, 68 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. * * * |