diff --git a/include/ck_bitmap.h b/include/ck_bitmap.h index 3c0105e..58cc91e 100644 --- a/include/ck_bitmap.h +++ b/include/ck_bitmap.h @@ -44,6 +44,7 @@ #endif #define CK_BITMAP_BLOCK (sizeof(unsigned int) * CHAR_BIT) +#define CK_BITMAP_OFFSET(i) ((i) % CK_BITMAP_BLOCK) #define CK_BITMAP_BIT(i) (1U << ((i) % CK_BITMAP_BLOCK)) #define CK_BITMAP_PTR(x, i) ((x) + ((i) / CK_BITMAP_BLOCK)) #define CK_BITMAP_BLOCKS(n) (((n) + CK_BITMAP_BLOCK - 1) / CK_BITMAP_BLOCK) @@ -69,6 +70,9 @@ #define CK_BITMAP_SET(a, b) \ ck_bitmap_set(&(a)->bitmap, (b)) +#define CK_BITMAP_BTS(a, b) \ + ck_bitmap_bts(&(a)->bitmap, (b)) + #define CK_BITMAP_RESET(a, b) \ ck_bitmap_reset(&(a)->bitmap, (b)) @@ -171,6 +175,19 @@ ck_bitmap_set(struct ck_bitmap *bitmap, unsigned int n) return; } +/* + * Performs a test-and-set operation at the offset specified in the + * second argument. + * Returns true if the bit at the specified offset was already set, + * false otherwise. + */ +CK_CC_INLINE static bool +ck_bitmap_bts(struct ck_bitmap *bitmap, unsigned int n) +{ + + return ck_pr_bts_uint(CK_BITMAP_PTR(bitmap->map, n), CK_BITMAP_OFFSET(n)); +} + /* * Resets the bit at the offset specified in the second argument. */ diff --git a/regressions/ck_bitmap/validate/serial.c b/regressions/ck_bitmap/validate/serial.c index 79aca8d..ecc5258 100644 --- a/regressions/ck_bitmap/validate/serial.c +++ b/regressions/ck_bitmap/validate/serial.c @@ -73,6 +73,7 @@ check_iteration(ck_bitmap_t *bits, unsigned int len, bool initial) static void test(ck_bitmap_t *bits, unsigned int n_length, bool initial) { + bool r; unsigned int i; CK_BITMAP_INSTANCE(8) u; @@ -92,14 +93,35 @@ test(ck_bitmap_t *bits, unsigned int n_length, bool initial) if (ck_bitmap_test(bits, i) == false) { ck_error("[1] ERROR: Expected bit to be set: %u\n", i); } + ck_bitmap_reset(bits, i); if (ck_bitmap_test(bits, i) == true) { ck_error("[2] ERROR: Expected bit to be cleared: %u\n", i); } + r = ck_bitmap_bts(bits, i); + if (r == true) { + ck_error("[3] ERROR: Expected bit to be cleared before 1st bts: %u\n", i); + } + if (ck_bitmap_test(bits, i) == false) { + ck_error("[4] ERROR: Expected bit to be set: %u\n", i); + } + r = ck_bitmap_bts(bits, i); + if (r == false) { + ck_error("[5] ERROR: Expected bit to be set before 2nd bts: %u\n", i); + } + if (ck_bitmap_test(bits, i) == false) { + ck_error("[6] ERROR: Expected bit to be set: %u\n", i); + } + + ck_bitmap_reset(bits, i); + if (ck_bitmap_test(bits, i) == true) { + ck_error("[7] ERROR: Expected bit to be cleared: %u\n", i); + } + ck_bitmap_set(bits, i); if (ck_bitmap_test(bits, i) == false) { - ck_error("[3] ERROR: Expected bit to be set: %u\n", i); + ck_error("[8] ERROR: Expected bit to be set: %u\n", i); } check_iteration(bits, i, initial); @@ -107,7 +129,7 @@ test(ck_bitmap_t *bits, unsigned int n_length, bool initial) for (i = 0; i < n_length; i++) { if (ck_bitmap_test(bits, i) == false) { - ck_error("[4] ERROR: Expected bit to be set: %u\n", i); + ck_error("[9] ERROR: Expected bit to be set: %u\n", i); } } @@ -115,7 +137,7 @@ test(ck_bitmap_t *bits, unsigned int n_length, bool initial) for (i = 0; i < n_length; i++) { if (ck_bitmap_test(bits, i) == true) { - ck_error("[4] ERROR: Expected bit to be reset: %u\n", i); + ck_error("[10] ERROR: Expected bit to be reset: %u\n", i); } }