Expand little endian bitops functions

We had the start of functions that operated on little endian bitmaps.
This adds more operations and uses __packed to support unaligned bitmaps
on platforms where unaligned accesses are a problem.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2016-07-27 13:50:51 -07:00
parent c48e08a378
commit 99167f6d66
+61 -3
View File
@@ -1,6 +1,13 @@
#ifndef _BITOPS_H_
#define _BITOPS_H_
/*
* Implement little endian bitmaps in terms of native longs. __packed
* is used to avoid unaligned accesses.
*/
typedef unsigned long * __packed ulong_ptr;
#define BITS_PER_LONG (sizeof(long) * 8)
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define BITOP_LE_SWIZZLE 0
@@ -8,13 +15,64 @@
#define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7)
#endif
static inline void set_bit_le(int nr, void *addr)
static inline ulong_ptr nr_word(int nr, ulong_ptr longs)
{
unsigned long *longs = addr;
return &longs[nr / BITS_PER_LONG];
}
static inline unsigned long nr_mask(int nr)
{
return 1UL << (nr % BITS_PER_LONG);
}
static inline int test_bit(int nr, ulong_ptr longs)
{
return !!(*nr_word(nr, longs) & nr_mask(nr));
}
static inline void set_bit(int nr, ulong_ptr longs)
{
*nr_word(nr, longs) |= nr_mask(nr);
}
static inline void clear_bit(int nr, ulong_ptr longs)
{
*nr_word(nr, longs) &= ~nr_mask(nr);
}
static inline int test_bit_le(int nr, void *addr)
{
return test_bit(nr ^ BITOP_LE_SWIZZLE, addr);
}
static inline int test_and_set_bit_le(int nr, void *addr)
{
int ret;
nr ^= BITOP_LE_SWIZZLE;
ret = test_bit(nr, addr);
set_bit(nr, addr);
return ret;
}
longs[nr / BITS_PER_LONG] |= 1UL << (nr & (BITS_PER_LONG - 1));
static inline void set_bit_le(int nr, void *addr)
{
set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
}
static inline void clear_bit_le(int nr, void *addr)
{
clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
}
static inline int test_and_clear_bit_le(int nr, void *addr)
{
int ret;
nr ^= BITOP_LE_SWIZZLE;
ret = test_bit(nr, addr);
clear_bit(nr, addr);
return ret;
}
#endif