commit ac0d3a625a5f0e2f81522b7d6d7ca6a6c3f158e2
Author:     Mattias Andrée <[email protected]>
AuthorDate: Tue Mar 15 23:19:01 2016 +0100
Commit:     Mattias Andrée <[email protected]>
CommitDate: Tue Mar 15 23:19:59 2016 +0100

    Fix bug in libzahl_msb_nz_* and optimise and simplify libzahl_realloc
    
    Signed-off-by: Mattias Andrée <[email protected]>

diff --git a/src/allocator.c b/src/allocator.c
index 7737046..80668f1 100644
--- a/src/allocator.c
+++ b/src/allocator.c
@@ -5,21 +5,15 @@
 void
 libzahl_realloc(z_t a, size_t need)
 {
-       size_t i, x;
+       size_t i, new_size = 1;
        zahl_char_t *new;
 
-       /* Find n such that n is a minimal power of 2 ≥ need. */
-       if (likely((need & (~need + 1)) != need)) {
-               need |= need >> 1;
-               need |= need >> 2;
-               need |= need >> 4;
-               for (i = sizeof(need), x = 8; (i >>= 1); x <<= 1)
-                       need |= need >> x;
-               need += 1;
+       new_size <<= i = libzahl_msb_nz_zu(need);
+       if (likely(new_size != need)) {
+               i += 1;
+               new_size <<= 1;
        }
 
-       i = libzahl_msb_nz_zu(need);
-
        if (likely(libzahl_pool_n[i])) {
                libzahl_pool_n[i]--;
                new = libzahl_pool[i][libzahl_pool_n[i]];
@@ -27,12 +21,12 @@ libzahl_realloc(z_t a, size_t need)
                zfree(a);
                a->chars = new;
        } else {
-               a->chars = realloc(a->chars, need * sizeof(zahl_char_t));
+               a->chars = realloc(a->chars, new_size * sizeof(zahl_char_t));
                if (unlikely(!a->chars)) {
                        if (!errno) /* sigh... */
                                errno = ENOMEM;
                        libzahl_failure(errno);
                }
        }
-       a->alloced = need;
+       a->alloced = new_size;
 }
diff --git a/src/internals.h b/src/internals.h
index da8ce0c..a9d9af5 100644
--- a/src/internals.h
+++ b/src/internals.h
@@ -150,15 +150,15 @@ zmemset(zahl_char_t *a, register zahl_char_t v, register 
size_t n)
 #endif
 
 #if defined(__GNUC__) || defined(__clang__)
-# define libzahl_msb_nz_lu(x)        (8 * sizeof(unsigned long int) - 
(size_t)__builtin_clzl(x));
-# define libzahl_msb_nz_llu(x)       (8 * sizeof(unsigned long long int) - 
(size_t)__builtin_clzll(x));
+# define libzahl_msb_nz_lu(x)        (8 * sizeof(unsigned long int) - 1 - 
(size_t)__builtin_clzl(x))
+# define libzahl_msb_nz_llu(x)       (8 * sizeof(unsigned long long int) - 1 - 
(size_t)__builtin_clzll(x))
 #else
 static inline size_t
 libzahl_msb_nz_lu(unsigned long int x)
 {
        size_t r = 0;
        for (; x; x >>= 1, r++);
-       return r;
+       return r - 1;
 }
 
 static inline size_t
@@ -166,7 +166,7 @@ libzahl_msb_nz_llu(unsigned long long int x)
 {
        size_t r = 0;
        for (; x; x >>= 1, r++);
-       return r;
+       return r - 1;
 }
 #endif
 

Reply via email to