From 8cd52802995365d781b09f9291e224959ed83b1c Mon Sep 17 00:00:00 2001 From: Josh Hursey Date: Thu, 9 Jun 2011 14:43:54 +0000 Subject: [PATCH] Some assorted opal_bitmap extensions * Protect the '->bitmap' field if init() is called more than once [it shouldn't be, but if it is then this avoids a memory leak]. * Some new functions * opal_bitmap_bitwise_and_inplace * opal_bitmap_bitwise_or_inplace * opal_bitmap_bitwise_xor_inplace * opal_bitmap_are_different * opal_bitmap_get_string Adding these features to the trunk so others have access to them if they need them. A couple off trunk branches make use of them. This commit was SVN r24767. --- opal/class/opal_bitmap.c | 146 +++++++++++++++++++++++++++++++++++++++ opal/class/opal_bitmap.h | 46 ++++++++++++ 2 files changed, 192 insertions(+) diff --git a/opal/class/opal_bitmap.c b/opal/class/opal_bitmap.c index 6a8895706b..b5ba126503 100644 --- a/opal/class/opal_bitmap.c +++ b/opal/class/opal_bitmap.c @@ -10,6 +10,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2010-2011 Oak Ridge National Labs. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -19,6 +20,7 @@ #include "opal_config.h" +#include #include #include "opal/constants.h" @@ -48,6 +50,7 @@ opal_bitmap_destruct(opal_bitmap_t *bm) { if (NULL != bm->bitmap) { free(bm->bitmap); + bm->bitmap = NULL; } } @@ -91,6 +94,9 @@ opal_bitmap_init(opal_bitmap_t *bm, int size) actual_size = size / SIZE_OF_CHAR; actual_size += (size % SIZE_OF_CHAR == 0) ? 0 : 1; bm->array_size = actual_size; + if( NULL != bm->bitmap ) { + free(bm->bitmap); + } bm->bitmap = (unsigned char *) malloc(actual_size); if (NULL == bm->bitmap) { return OPAL_ERR_OUT_OF_RESOURCE; @@ -266,3 +272,143 @@ opal_bitmap_find_and_set_first_unset_bit(opal_bitmap_t *bm, int *position) (*position) += i * SIZE_OF_CHAR; return OPAL_SUCCESS; } + +int opal_bitmap_bitwise_and_inplace(opal_bitmap_t *dest, opal_bitmap_t *right) +{ + int i; + + /* + * Sanity check + */ + if( NULL == dest || NULL == right ) { + return OPAL_ERR_BAD_PARAM; + } + if( dest->array_size != right->array_size ) { + return OPAL_ERR_BAD_PARAM; + } + + /* + * Bitwise AND + */ + for(i = 0; i < dest->array_size; ++i) { + dest->bitmap[i] &= right->bitmap[i]; + } + + return OPAL_SUCCESS; +} + +int opal_bitmap_bitwise_or_inplace(opal_bitmap_t *dest, opal_bitmap_t *right) +{ + int i; + + /* + * Sanity check + */ + if( NULL == dest || NULL == right ) { + return OPAL_ERR_BAD_PARAM; + } + if( dest->array_size != right->array_size ) { + return OPAL_ERR_BAD_PARAM; + } + + /* + * Bitwise OR + */ + for(i = 0; i < dest->array_size; ++i) { + dest->bitmap[i] |= right->bitmap[i]; + } + + return OPAL_SUCCESS; +} + +int opal_bitmap_bitwise_xor_inplace(opal_bitmap_t *dest, opal_bitmap_t *right) +{ + int i; + + /* + * Sanity check + */ + if( NULL == dest || NULL == right ) { + return OPAL_ERR_BAD_PARAM; + } + if( dest->array_size != right->array_size ) { + return OPAL_ERR_BAD_PARAM; + } + + /* + * Bitwise XOR + */ + for(i = 0; i < dest->array_size; ++i) { + dest->bitmap[i] ^= right->bitmap[i]; + } + + return OPAL_SUCCESS; +} + +bool opal_bitmap_are_different(opal_bitmap_t *left, opal_bitmap_t *right) +{ + int i; + + /* + * Sanity check + */ + if( NULL == left || NULL == right ) { + return OPAL_ERR_BAD_PARAM; + } + + if( opal_bitmap_size(left) != opal_bitmap_size(right) ) { + return true; + } + + /* + * Direct comparison + */ + for(i = 0; i < left->array_size; ++i) { + if( left->bitmap[i] != right->bitmap[i] ) { + return true; + } + } + + return false; +} + +char * opal_bitmap_get_string(opal_bitmap_t *bitmap) +{ + int i; + char *tmp_str = NULL; + char *bitmap_str = NULL; + char cur_char = ' '; + + if( NULL == bitmap) { + return NULL; + } + + for( i = 0; i < (bitmap->array_size * SIZE_OF_CHAR); ++i) { + if( opal_bitmap_is_set_bit(bitmap, i) ) { + cur_char = 'X'; + } else { + cur_char = '_'; + } + + if( NULL == bitmap_str ) { + asprintf(&tmp_str, "%c", cur_char); + } else { + asprintf(&tmp_str, "%s%c", bitmap_str, cur_char); + } + + if( NULL != bitmap_str ) { + free(bitmap_str); + bitmap_str = NULL; + } + bitmap_str = strdup(tmp_str); + free(tmp_str); + tmp_str = NULL; + } + + if( NULL != tmp_str ) { + free(tmp_str); + tmp_str = NULL; + } + + return bitmap_str; +} diff --git a/opal/class/opal_bitmap.h b/opal/class/opal_bitmap.h index a27a754668..162f22a979 100644 --- a/opal/class/opal_bitmap.h +++ b/opal/class/opal_bitmap.h @@ -11,6 +11,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2010-2011 Oak Ridge National Labs. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -182,6 +183,51 @@ static inline void opal_bitmap_copy(opal_bitmap_t *dest, opal_bitmap_t *src) dest->array_size = src->array_size; } +/** + * Bitwise AND operator (inplace) + * + * @param dest Pointer to the bitmap that should be modified + * @param right Point to the other bitmap in the operation + * @return OPAL error code if the length of the two bitmaps is not equal or one is NULL. + */ +OPAL_DECLSPEC int opal_bitmap_bitwise_and_inplace(opal_bitmap_t *dest, opal_bitmap_t *right); + +/** + * Bitwise OR operator (inplace) + * + * @param dest Pointer to the bitmap that should be modified + * @param right Point to the other bitmap in the operation + * @return OPAL error code if the length of the two bitmaps is not equal or one is NULL. + */ +OPAL_DECLSPEC int opal_bitmap_bitwise_or_inplace(opal_bitmap_t *dest, opal_bitmap_t *right); + +/** + * Bitwise XOR operator (inplace) + * + * @param dest Pointer to the bitmap that should be modified + * @param right Point to the other bitmap in the operation + * @return OPAL error code if the length of the two bitmaps is not equal or one is NULL. + */ +OPAL_DECLSPEC int opal_bitmap_bitwise_xor_inplace(opal_bitmap_t *dest, opal_bitmap_t *right); + +/** + * If the bitmaps are different + * + * @param left Pointer to a bitmap + * @param right Pointer to another bitmap + * @return true if different, false if the same + */ +OPAL_DECLSPEC bool opal_bitmap_are_different(opal_bitmap_t *left, opal_bitmap_t *right); + +/** + * Get a string representation of the bitmap. + * Useful for debugging. + * + * @param bitmap Point to the bitmap to represent + * @return Pointer to the string (caller must free if not NULL) + */ +OPAL_DECLSPEC char * opal_bitmap_get_string(opal_bitmap_t *bitmap); + END_C_DECLS #endif