diff --git a/src/lfc/lam_bitmap.c b/src/lfc/lam_bitmap.c index 2faa506e28..e839e7853c 100644 --- a/src/lfc/lam_bitmap.c +++ b/src/lfc/lam_bitmap.c @@ -5,7 +5,6 @@ #include "lfc/lam_bitmap.h" #define SIZE_OF_CHAR (sizeof(char) * 8) -#define LAM_INVALID_BIT -1 static void lam_bitmap_construct(lam_bitmap_t *bm); static void lam_bitmap_destruct(lam_bitmap_t *bm); @@ -21,7 +20,7 @@ lam_class_t lam_bitmap_t_class = { static void lam_bitmap_construct(lam_bitmap_t *bm) { - bm->size = 0; + bm->legal_numbits = 0; bm->array_size = 0; bm->bitmap = NULL; } @@ -36,11 +35,17 @@ lam_bitmap_destruct(lam_bitmap_t *bm) int lam_bitmap_init(lam_bitmap_t *bm, size_t size) { - size_t actual_size = size / SIZE_OF_CHAR; + + size_t actual_size; + + if (((int)size <= 0) || (NULL == bm)) + return LAM_ERR_ARG; + + bm->legal_numbits = size; + actual_size = size / SIZE_OF_CHAR; actual_size += (size % SIZE_OF_CHAR == 0) ? 0 : 1; - bm->size = actual_size * SIZE_OF_CHAR; - bm->bitmap = (char *) realloc(bm->bitmap, actual_size); + bm->bitmap = (unsigned char *) malloc(actual_size); if (NULL == bm->bitmap) return LAM_ERR_SYSRESOURCE; @@ -56,19 +61,22 @@ lam_bitmap_set_bit(lam_bitmap_t *bm, int bit) size_t index, offset, new_size; int i; - index = bit / SIZE_OF_CHAR - 1; - offset = bit % SIZE_OF_CHAR -1; + if ((bit < 0) || (NULL == bm)) + return LAM_ERR_ARG; + + index = bit / SIZE_OF_CHAR; + offset = bit % SIZE_OF_CHAR; if (index >= bm->array_size) { /* We need to allocate more space for the bitmap, since we are out of range. We dont throw any error here, because this is valid and we simply expand the bitmap */ - new_size = index / bm->array_size * bm->array_size; + new_size = (index / bm->array_size + 1 ) * bm->array_size; /* New size is just a multiple of the original size to fit in the index */ - bm->bitmap = (char *) realloc(bm->bitmap, new_size); + bm->bitmap = (unsigned char *) realloc(bm->bitmap, new_size); if (NULL == bm->bitmap) { return LAM_ERR_SYSRESOURCE; } @@ -77,8 +85,15 @@ lam_bitmap_set_bit(lam_bitmap_t *bm, int bit) for (i = bm->array_size; i < new_size; ++i) { bm->bitmap[i] = 0; } + + /* Update the array_size */ + bm->array_size = new_size; + bm->legal_numbits = bit + 1; } + + /* Now set the bit */ bm->bitmap[index] |= (1 << offset); + return 0; } @@ -87,8 +102,11 @@ int lam_bitmap_clear_bit(lam_bitmap_t *bm, int bit) { size_t index, offset; - - index = bit / SIZE_OF_CHAR - 1; + + if ((bit < 0) || (bit > bm->legal_numbits - 1) || (NULL == bm)) + return LAM_ERR_ARG; + + index = bit / SIZE_OF_CHAR; offset = bit % SIZE_OF_CHAR; if (index >= bm->array_size) { @@ -105,65 +123,94 @@ lam_bitmap_is_set_bit(lam_bitmap_t *bm, int bit) { size_t index, offset; - index = bit / SIZE_OF_CHAR - 1; - offset = bit % SIZE_OF_CHAR -1; + if ((bit < 0) || (bit > bm->legal_numbits - 1) || (NULL == bm)) + return LAM_ERR_ARG; + + + index = bit / SIZE_OF_CHAR; + offset = bit % SIZE_OF_CHAR; if (index >= bm->array_size) { return LAM_INVALID_BIT; } - if ((0 != bm->bitmap[index]) & (1 << offset)) + if (0 != (bm->bitmap[index] & (1 << offset))) return 1; return 0; } -void +int lam_bitmap_clear_all_bits(lam_bitmap_t *bm) { + if (NULL == bm) + return LAM_ERR_ARG; + memset(bm->bitmap, 0, bm->array_size); -} - - -void -lam_bitmap_set_all_bits(lam_bitmap_t *bm) -{ - int i; - for (i = 0; i < bm->array_size; ++i) { - bm->bitmap[i] = ~((char) 0); - } + return 0; } int -lam_bitmap_find_and_set_first_unset_bit(lam_bitmap_t *bm) +lam_bitmap_set_all_bits(lam_bitmap_t *bm) { - size_t i; - int position = 0; - char temp; + int i; + + if (NULL == bm) + return LAM_ERR_ARG; + for (i = 0; i < bm->array_size; ++i) { - - /* Neglect all which dont have an unset bit */ - while (bm->bitmap[i] == (char)~0) - continue; - - /* This one has an unset bit, find its bit number */ - temp = bm->bitmap[i]; - while (temp & 0x1) { - ++position; - temp >>= 1; - } - - /* Now set the bit number */ - bm->bitmap[i] |= (bm->bitmap[i] + 1); + bm->bitmap[i] = ~((char) 0); } return 0; } +#include +int +lam_bitmap_find_and_set_first_unset_bit(lam_bitmap_t *bm) +{ + size_t i = 0; + int position = 0; + unsigned char temp; + unsigned char all_ones = 0xff; + + if (NULL == bm) + return LAM_ERR_ARG; + + /* Neglect all which dont have an unset bit */ + while((i < bm->array_size) && (bm->bitmap[i] == all_ones)) { + ++i; + } + + if (i == bm->array_size) { + /* increase the bitmap size then */ + position = bm->array_size * SIZE_OF_CHAR; + lam_bitmap_set_bit(bm, position); + return position; + } + + /* This one has an unset bit, find its bit number */ + + temp = bm->bitmap[i]; + while (temp & 0x1) { + ++position; + temp >>= 1; + } + + /* Now set the bit number */ + bm->bitmap[i] |= (bm->bitmap[i] + 1); + + position += i * SIZE_OF_CHAR; + return position; +} + size_t lam_bitmap_size(lam_bitmap_t *bm) { - return bm->size; + if (NULL == bm) + return LAM_ERR_ARG; + + return bm->legal_numbits; } diff --git a/src/lfc/lam_bitmap.h b/src/lfc/lam_bitmap.h index 9dfc37daf2..d84ca8465f 100644 --- a/src/lfc/lam_bitmap.h +++ b/src/lfc/lam_bitmap.h @@ -5,8 +5,14 @@ /** @file * - * A bitmap implementation. The bits start off with 0, so this - * bitmap has bits numbered as bit 0, bit 1, bit 2 and so on + * A bitmap implementation. The bits start off with 0, so this bitmap + * has bits numbered as bit 0, bit 1, bit 2 and so on. This bitmap + * has auto-expansion capabilities, that is once the size is set + * during init, it can be automatically expanded by setting the bit + * beyond the current size. But note, this is allowed just when the + * bit is set -- so the valid functions are set_bit and + * find_and_set_bit. Other functions like clear, if passed a bit + * outside the initialized range will result in an error. */ #ifndef LAM_BITMAP_H @@ -19,15 +25,21 @@ #include "lfc/lam_object.h" /* VPS: Just to compile right now, has to move later on */ + #define LAM_ERR_SYSRESOURCE -1 +#define LAM_INVALID_BIT -1 +#define LAM_ERR_ARG -2 extern lam_class_t lam_bitmap_t_class; struct lam_bitmap_t { lam_object_t super; /**< Subclass of lam_object_t */ - char *bitmap; /**< The actual bitmap array of characters */ - size_t size; /**< The number of bits in the bitmap */ + unsigned char *bitmap; /**< The actual bitmap array of characters */ size_t array_size; /**< The actual array size that maintains the bitmap */ + size_t legal_numbits; /**< The number of bits which are legal (the + actual bitmap may contain more bits, since + it needs to be rounded to the nearest + char */ }; typedef struct lam_bitmap_t lam_bitmap_t; @@ -100,23 +112,27 @@ int lam_bitmap_find_and_set_first_unset_bit(lam_bitmap_t *bm); * Clear all bits in the bitmap * * @param bitmap The input bitmap (IN) + * @return LAM error code if bm is NULL * */ -void lam_bitmap_clear_all_bits(lam_bitmap_t *bm); +int lam_bitmap_clear_all_bits(lam_bitmap_t *bm); /** * Set all bits in the bitmap * @param bitmap The input bitmap (IN) + * @return LAM error code if bm is NULL * */ -void lam_bitmap_set_all_bits(lam_bitmap_t *bm); +int lam_bitmap_set_all_bits(lam_bitmap_t *bm); /** - * Gives the current size (number of bits) in the bitmap + * Gives the current size (number of bits) in the bitmap. This is the + * legal (accessible) number of bits * * @param bitmap The input bitmap (IN) + * @return LAM error code if bm is NULL * */ size_t lam_bitmap_size (lam_bitmap_t *bm);