From 65a4b8d9c1929fb7b171d630d336519fc4d418ef Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 24 Sep 2016 22:33:05 +0200 Subject: Replaced the non-working GLib atomic function to deal with bitfields. --- ChangeLog | 5 +++++ src/common/bits.c | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5c8b68e..6e8a942 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +16-09-24 Cyrille Bagard + + * src/common/bits.c: + Replace the non-working GLib atomic function to deal with bitfields. + 16-09-23 Cyrille Bagard * src/analysis/disass/output.c: diff --git a/src/common/bits.c b/src/common/bits.c index 42493f2..2aa1be5 100644 --- a/src/common/bits.c +++ b/src/common/bits.c @@ -356,31 +356,51 @@ bool set_atomic_in_bit_field(bitfield_t *field, size_t first, size_t count) 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 */ + unsigned long oldval; /* Ancienne valeur présente */ 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); + assert(count > 0 && count <= (sizeof(unsigned long) * 8)); - mask = (1 << count) - 1; - mask <<= remaining; + if (count == 64) + { + assert(remaining == 0); + mask = ~0lu; + } + else + { + mask = (1lu << count) - 1; + mask <<= remaining; + } - oldval = g_atomic_pointer_or(&field->bits[start], mask); + /** + * Pour une raison inconnue, l'appel suivant est parfois sans effet : + * + * oldval = g_atomic_pointer_or(&field->bits[start], mask); + * + * On bascule donc dans l'équivalent plus long à exécuter... + */ + + g_mutex_lock(&field->mutex); + + oldval = field->bits[start]; + + field->bits[start] |= mask; + + g_mutex_unlock(&field->mutex); result = ((oldval & mask) == 0); + assert(test_in_bit_field(field, first, count)); + } else -#endif { g_mutex_lock(&field->mutex); -- cgit v0.11.2-87-g4458