mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-23 02:14:37 +00:00
Grabbed from kernel. Probably worth to gather all bits manipulators here in future. Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
54 lines
1.3 KiB
C
54 lines
1.3 KiB
C
#include "asm/bitsperlong.h"
|
|
|
|
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
|
|
|
|
#define BITMAP_FIRST_WORD_MASK(start) (~0ul << ((start) % BITS_PER_LONG))
|
|
|
|
#define BITMAP_LAST_WORD_MASK(nbits) \
|
|
( \
|
|
((nbits) % BITS_PER_LONG) ? \
|
|
(1ul << ((nbits) % BITS_PER_LONG)) - 1 : ~0ul \
|
|
)
|
|
|
|
#define small_const_nbits(nbits) \
|
|
(__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
|
|
|
|
void bitmap_set(unsigned long *map, int start, int nr)
|
|
{
|
|
unsigned long *p = map + BIT_WORD(start);
|
|
const int size = start + nr;
|
|
int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
|
|
unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
|
|
|
|
while (nr - bits_to_set >= 0) {
|
|
*p |= mask_to_set;
|
|
nr -= bits_to_set;
|
|
bits_to_set = BITS_PER_LONG;
|
|
mask_to_set = ~0UL;
|
|
p++;
|
|
}
|
|
if (nr) {
|
|
mask_to_set &= BITMAP_LAST_WORD_MASK(size);
|
|
*p |= mask_to_set;
|
|
}
|
|
}
|
|
|
|
void bitmap_clear(unsigned long *map, int start, int nr)
|
|
{
|
|
unsigned long *p = map + BIT_WORD(start);
|
|
const int size = start + nr;
|
|
int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
|
|
unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
|
|
|
|
while (nr - bits_to_clear >= 0) {
|
|
*p &= ~mask_to_clear;
|
|
nr -= bits_to_clear;
|
|
bits_to_clear = BITS_PER_LONG;
|
|
mask_to_clear = ~0UL;
|
|
p++;
|
|
}
|
|
if (nr) {
|
|
mask_to_clear &= BITMAP_LAST_WORD_MASK(size);
|
|
*p &= ~mask_to_clear;
|
|
}
|
|
}
|