mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
LinuxKPI: Add bitmap_intersects(), bitmap_from_arr32()
and bitmap_shift_right() functions to linux/bitmap.h They perform calculation of two bitmaps intersection, copying the contents of u32 array of bits to bitmap and logical right shifting of the bits in a bitmap. Sponsored by: Serenity Cyber Security, LLC Reviewed by: manu MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D42812 (cherry picked from commit 5ae2e6f913fa1df5f3262255558b76af05409a09)
This commit is contained in:
parent
cdceed0413
commit
edeb8cfad0
1 changed files with 78 additions and 0 deletions
|
|
@ -264,6 +264,27 @@ bitmap_subset(const unsigned long *pa,
|
|||
return (1);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
bitmap_intersects(const unsigned long *pa, const unsigned long *pb,
|
||||
unsigned size)
|
||||
{
|
||||
const unsigned end = BIT_WORD(size);
|
||||
const unsigned tail = size & (BITS_PER_LONG - 1);
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i != end; i++)
|
||||
if (pa[i] & pb[i])
|
||||
return (true);
|
||||
|
||||
if (tail) {
|
||||
const unsigned long mask = BITMAP_LAST_WORD_MASK(tail);
|
||||
|
||||
if (pa[end] & pb[end] & mask)
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bitmap_complement(unsigned long *dst, const unsigned long *src,
|
||||
const unsigned int size)
|
||||
|
|
@ -306,6 +327,29 @@ bitmap_to_arr32(uint32_t *dst, const unsigned long *src, unsigned int size)
|
|||
dst[end - 1] &= (uint32_t)(UINT_MAX >> (32 - (size % 32)));
|
||||
}
|
||||
|
||||
static inline void
|
||||
bitmap_from_arr32(unsigned long *dst, const uint32_t *src,
|
||||
unsigned int size)
|
||||
{
|
||||
const unsigned int end = BIT_WORD(size);
|
||||
const unsigned int tail = size & (BITS_PER_LONG - 1);
|
||||
|
||||
#ifdef __LP64__
|
||||
const unsigned int end32 = howmany(size, 32);
|
||||
unsigned int i = 0;
|
||||
|
||||
while (i < end32) {
|
||||
dst[i++/2] = (unsigned long) *(src++);
|
||||
if (i < end32)
|
||||
dst[i++/2] |= ((unsigned long) *(src++)) << 32;
|
||||
}
|
||||
#else
|
||||
bitmap_copy(dst, (unsigned long *)src, size);
|
||||
#endif
|
||||
if ((size % BITS_PER_LONG) != 0)
|
||||
dst[end] &= BITMAP_LAST_WORD_MASK(tail);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bitmap_or(unsigned long *dst, const unsigned long *src1,
|
||||
const unsigned long *src2, const unsigned int size)
|
||||
|
|
@ -350,6 +394,40 @@ bitmap_xor(unsigned long *dst, const unsigned long *src1,
|
|||
dst[i] = src1[i] ^ src2[i];
|
||||
}
|
||||
|
||||
static inline void
|
||||
bitmap_shift_right(unsigned long *dst, const unsigned long *src,
|
||||
unsigned int shift, unsigned int size)
|
||||
{
|
||||
const unsigned int end = BITS_TO_LONGS(size);
|
||||
const unsigned int tail = size & (BITS_PER_LONG - 1);
|
||||
const unsigned long mask = BITMAP_LAST_WORD_MASK(tail);
|
||||
const unsigned int off = BIT_WORD(shift);
|
||||
const unsigned int rem = shift & (BITS_PER_LONG - 1);
|
||||
unsigned long left, right;
|
||||
unsigned int i, srcpos;
|
||||
|
||||
for (i = 0, srcpos = off; srcpos < end; i++, srcpos++) {
|
||||
right = src[srcpos];
|
||||
left = 0;
|
||||
|
||||
if (srcpos == end - 1)
|
||||
right &= mask;
|
||||
|
||||
if (rem != 0) {
|
||||
right >>= rem;
|
||||
if (srcpos + 1 < end) {
|
||||
left = src[srcpos + 1];
|
||||
if (srcpos + 1 == end - 1)
|
||||
left &= mask;
|
||||
left <<= (BITS_PER_LONG - rem);
|
||||
}
|
||||
}
|
||||
dst[i] = left | right;
|
||||
}
|
||||
if (off != 0)
|
||||
memset(dst + end - off, 0, off * sizeof(unsigned long));
|
||||
}
|
||||
|
||||
static inline unsigned long *
|
||||
bitmap_alloc(unsigned int size, gfp_t flags)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue