diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-09-24 20:33:05 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-09-24 20:33:05 (GMT) |
commit | 65a4b8d9c1929fb7b171d630d336519fc4d418ef (patch) | |
tree | 1883080d3b92989d9c06f8d5085a54b7e6aad0b9 | |
parent | e2bce994e554cb598ed9547ba5ecf22be748ddfd (diff) |
Replaced the non-working GLib atomic function to deal with bitfields.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | src/common/bits.c | 38 |
2 files changed, 34 insertions, 9 deletions
@@ -1,3 +1,8 @@ +16-09-24 Cyrille Bagard <nocbos@gmail.com> + + * src/common/bits.c: + Replace the non-working GLib atomic function to deal with bitfields. + 16-09-23 Cyrille Bagard <nocbos@gmail.com> * 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); |