diff options
author | Olaf Hering <olaf@aepfle.de> | 2011-06-10 10:47:03 +0200 |
---|---|---|
committer | Olaf Hering <olaf@aepfle.de> | 2011-06-10 10:47:03 +0200 |
commit | aa1355f971287932e2ba09dfb04a6122ecc3951f (patch) | |
tree | b84ec9861d1b3409fed90ebaa7e6b8d857af4a3b /tools/libxc/xc_bitops.h | |
parent | 9c1ebbba309d04e15c8bc768843127c2c8b84c5f (diff) | |
download | xen-aa1355f971287932e2ba09dfb04a6122ecc3951f.tar.gz xen-aa1355f971287932e2ba09dfb04a6122ecc3951f.tar.bz2 xen-aa1355f971287932e2ba09dfb04a6122ecc3951f.zip |
tools: merge several bitop functions into xc_bitops.h
Bitmaps are used in save/restore, xenpaging and blktap2. Merge the code into a
private xc_bitops.h file. All users are single threaded, so locking is not an
issue. The array of bits is handled as volatile because the x86 save/restore
code passes the bitmap to the hypervisor which in turn modifies the bitmap.
blktap2 uses a private bitmap. There was a possible overflow in the
bitmap_size() function, the remainder was not considered.
ia64 save/restore uses a bitmap to send the number of vcpus to the host.
x86 save/restore uses a bitmap to track dirty pages. This bitmap is shared with
the hypervisor. An unused function count_bits() was removed and a new
bitmap_size() function is now used.
xenpaging uses 3 private bitmaps to track the gfns which are in paged-out
state. It had a copy of some Linux bitops.h, which is now obsolete. Also the
BITS_PER_LONG macro was hardcoded to 64 which made it impossible to run 32bit
tools on a 64bit host. Wether this works at all has to be tested, yet.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
Diffstat (limited to 'tools/libxc/xc_bitops.h')
-rw-r--r-- | tools/libxc/xc_bitops.h | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/tools/libxc/xc_bitops.h b/tools/libxc/xc_bitops.h new file mode 100644 index 0000000000..8ee2aab95f --- /dev/null +++ b/tools/libxc/xc_bitops.h @@ -0,0 +1,57 @@ +#ifndef XC_BITOPS_H +#define XC_BITOPS_H 1 + +/* bitmap operations for single threaded access */ + +#include <stdlib.h> + +#define BITS_PER_LONG (sizeof(unsigned long) * 8) +#define ORDER_LONG (sizeof(unsigned long) == 4 ? 5 : 6) + +#define BITMAP_ENTRY(_nr,_bmap) ((_bmap))[(_nr)/BITS_PER_LONG] +#define BITMAP_SHIFT(_nr) ((_nr) % BITS_PER_LONG) + +/* calculate required space for number of longs needed to hold nr_bits */ +static inline int bitmap_size(int nr_bits) +{ + int nr_long, nr_bytes; + nr_long = (nr_bits + BITS_PER_LONG - 1) >> ORDER_LONG; + nr_bytes = nr_long * sizeof(unsigned long); + return nr_bytes; +} + +static inline unsigned long *bitmap_alloc(int nr_bits) +{ + return calloc(1, bitmap_size(nr_bits)); +} + +static inline int test_bit(int nr, volatile unsigned long *addr) +{ + return (BITMAP_ENTRY(nr, addr) >> BITMAP_SHIFT(nr)) & 1; +} + +static inline void clear_bit(int nr, volatile unsigned long *addr) +{ + BITMAP_ENTRY(nr, addr) &= ~(1UL << BITMAP_SHIFT(nr)); +} + +static inline void set_bit(int nr, volatile unsigned long *addr) +{ + BITMAP_ENTRY(nr, addr) |= (1UL << BITMAP_SHIFT(nr)); +} + +static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) +{ + int oldbit = test_bit(nr, addr); + clear_bit(nr, addr); + return oldbit; +} + +static inline int test_and_set_bit(int nr, volatile unsigned long *addr) +{ + int oldbit = test_bit(nr, addr); + set_bit(nr, addr); + return oldbit; +} + +#endif /* XC_BITOPS_H */ |