core-lightning/ccan/ccan/bitmap/bitmap.c
Rusty Russell 641876a20a ccan: update to latest.
configurator failed under clang:

checking for #pragma omp and -fopenmp support... ccan/tools/configurator/configurator: Test for HAVE_OPENMP failed with 32512:
./configurator.out: error while loading shared libraries: libomp.so: cannot open shared object file: No such file or directory

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2019-08-02 15:56:15 +02:00

125 lines
2.6 KiB
C

/* Licensed under LGPLv2.1+ - see LICENSE file for details */
#include "config.h"
#include <ccan/bitmap/bitmap.h>
#include <assert.h>
#define BIT_ALIGN_DOWN(n) ((n) & ~(BITMAP_WORD_BITS - 1))
#define BIT_ALIGN_UP(n) BIT_ALIGN_DOWN((n) + BITMAP_WORD_BITS - 1)
void bitmap_zero_range(bitmap *bitmap, unsigned long n, unsigned long m)
{
unsigned long an = BIT_ALIGN_UP(n);
unsigned long am = BIT_ALIGN_DOWN(m);
bitmap_word headmask = BITMAP_WORD_1 >> (n % BITMAP_WORD_BITS);
bitmap_word tailmask = ~(BITMAP_WORD_1 >> (m % BITMAP_WORD_BITS));
assert(m >= n);
if (am < an) {
BITMAP_WORD(bitmap, n) &= ~bitmap_bswap(headmask & tailmask);
return;
}
if (an > n)
BITMAP_WORD(bitmap, n) &= ~bitmap_bswap(headmask);
if (am > an)
memset(&BITMAP_WORD(bitmap, an), 0,
(am - an) / BITMAP_WORD_BITS * sizeof(bitmap_word));
if (m > am)
BITMAP_WORD(bitmap, m) &= ~bitmap_bswap(tailmask);
}
void bitmap_fill_range(bitmap *bitmap, unsigned long n, unsigned long m)
{
unsigned long an = BIT_ALIGN_UP(n);
unsigned long am = BIT_ALIGN_DOWN(m);
bitmap_word headmask = BITMAP_WORD_1 >> (n % BITMAP_WORD_BITS);
bitmap_word tailmask = ~(BITMAP_WORD_1 >> (m % BITMAP_WORD_BITS));
assert(m >= n);
if (am < an) {
BITMAP_WORD(bitmap, n) |= bitmap_bswap(headmask & tailmask);
return;
}
if (an > n)
BITMAP_WORD(bitmap, n) |= bitmap_bswap(headmask);
if (am > an)
memset(&BITMAP_WORD(bitmap, an), 0xff,
(am - an) / BITMAP_WORD_BITS * sizeof(bitmap_word));
if (m > am)
BITMAP_WORD(bitmap, m) |= bitmap_bswap(tailmask);
}
static int bitmap_clz(bitmap_word w)
{
#if HAVE_BUILTIN_CLZL
return __builtin_clzl(w);
#else
int lz = 0;
bitmap_word mask = (bitmap_word)1 << (BITMAP_WORD_BITS - 1);
while (!(w & mask)) {
lz++;
mask >>= 1;
}
return lz;
#endif
}
unsigned long bitmap_ffs(const bitmap *bitmap,
unsigned long n, unsigned long m)
{
unsigned long an = BIT_ALIGN_UP(n);
unsigned long am = BIT_ALIGN_DOWN(m);
bitmap_word headmask = BITMAP_WORD_1 >> (n % BITMAP_WORD_BITS);
bitmap_word tailmask = ~(BITMAP_WORD_1 >> (m % BITMAP_WORD_BITS));
assert(m >= n);
if (am < an) {
bitmap_word w = bitmap_bswap(BITMAP_WORD(bitmap, n));
w &= (headmask & tailmask);
return w ? am + bitmap_clz(w) : m;
}
if (an > n) {
bitmap_word w = bitmap_bswap(BITMAP_WORD(bitmap, n));
w &= headmask;
if (w)
return BIT_ALIGN_DOWN(n) + bitmap_clz(w);
}
while (an < am) {
bitmap_word w = bitmap_bswap(BITMAP_WORD(bitmap, an));
if (w)
return an + bitmap_clz(w);
an += BITMAP_WORD_BITS;
}
if (m > am) {
bitmap_word w = bitmap_bswap(BITMAP_WORD(bitmap, m));
w &= tailmask;
if (w)
return am + bitmap_clz(w);
}
return m;
}