diff --git a/Makefile b/Makefile index 94aa600..440aff4 100644 --- a/Makefile +++ b/Makefile @@ -5,16 +5,16 @@ SHARED_LIB = libsparsemap.so #CFLAGS = -Wall -Wextra -Wpedantic -Of -std=c11 -Iinclude/ -fPIC #CFLAGS = -Wall -Wextra -Wpedantic -Og -g -std=c11 -Iinclude/ -fPIC -#CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -O0 -g -std=c11 -Iinclude/ -fPIC -CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -fPIC +CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -D_FORTIFY_SOURCE=0 -O0 -g -std=c11 -Iinclude/ -fPIC +#CFLAGS = -DREENTRENT_SPARSEMAP -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -fPIC #CFLAGS = -Wall -Wextra -Wpedantic -Og -g -std=c11 -Iinclude/ -fPIC #CFLAGS = -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -fPIC #CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -Og -g -fsanitize=address,leak,object-size,pointer-compare,pointer-subtract,null,return,bounds,pointer-overflow,undefined -fsanitize-address-use-after-scope -std=c11 -Iinclude/ -fPIC #CFLAGS = -Wall -Wextra -Wpedantic -Og -g -fsanitize=all -fhardened -std=c11 -Iinclude/ -fPIC -#TEST_FLAGS = -DDEBUG -Wall -Wextra -Wpedantic -O0 -g -std=c11 -Iinclude/ -Itests/ -fPIC +TEST_FLAGS = -DREENTRENT_SPARSEMAP -DDEBUG -Wall -Wextra -Wpedantic -O0 -D_FORTIFY_SOURCE=0 -g -std=c11 -Iinclude/ -Itests/ -fPIC #TEST_FLAGS = -Wall -Wextra -Wpedantic -Og -g -std=c11 -Iinclude/ -Itests/ -fPIC -TEST_FLAGS = -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -Itests/ -fPIC +#TEST_FLAGS = -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -Itests/ -fPIC #TEST_FLAGS = -DDEBUG -Wall -Wextra -Wpedantic -Og -g -fsanitize=address,leak,object-size,pointer-compare,pointer-subtract,null,return,bounds,pointer-overflow,undefined -fsanitize-address-use-after-scope -std=c11 -Iinclude/ -fPIC TESTS = tests/test diff --git a/include/sparsemap.h b/include/sparsemap.h index bf749aa..a08e386 100644 --- a/include/sparsemap.h +++ b/include/sparsemap.h @@ -109,6 +109,9 @@ typedef uint64_t sm_bitvec_t; * @returns The newly allocated sparsemap reference. */ sparsemap_t *sparsemap(size_t size); +#ifdef REENTRENT_SPARSEMAP +sparsemap_t *sparsemap_r(size_t size); +#endif /** @brief Allocate a new, empty sparsemap_t that references (wraps) the buffer * \b data of \b size bytes to use for storage of bitmap data. @@ -190,6 +193,9 @@ void sparsemap_clear(sparsemap_t *map); * supported. */ sparsemap_t *sparsemap_set_data_size(sparsemap_t *map, size_t size, uint8_t *data); +#ifdef REENTRENT_SPARSEMAP +sparsemap_t *sparsemap_set_data_size_r(sparsemap_t *map, size_t size, uint8_t *data); +#endif /** @brief Calculate remaining capacity, approaches 0 when full. * diff --git a/src/sparsemap.c b/src/sparsemap.c index 718c4ef..52575e5 100644 --- a/src/sparsemap.c +++ b/src/sparsemap.c @@ -33,6 +33,9 @@ #include #include #include +#ifdef REENTRENT_SPARSEMAP +#include +#endif #ifdef SPARSEMAP_DIAGNOSTIC #pragma GCC diagnostic push @@ -109,6 +112,7 @@ enum __SM_CHUNK_INFO { }; #define SM_CHUNK_GET_FLAGS(from, at) (((from)) & ((sm_bitvec_t)SM_FLAG_MASK << ((at)*2))) >> ((at)*2) +gsb #define SM_IS_REENTRENT(from) (((from)) & ((sm_bitvec_t)SM_FLAG_MASK) typedef struct { sm_bitvec_t *m_data; @@ -966,6 +970,19 @@ sparsemap(size_t size) return map; } +#ifdef REENTRENT_SPARSEMAP +sparsemap_t * +sparsemap_r(size_t size) +{ + sparsemap_t *map = sparsemap(size + sizeof(pthread_mutex_t)); + sparsemap_t *rm = (sparsemap_t *)((uintptr_t)map + sizeof(pthread_mutex_t)); + pthread_mutex_t *mutex = (pthread_mutex_t *)map; + memcpy(rm, map, size); + pthread_mutex_init(mutex, NULL); + return map; +} +#endif + sparsemap_t * sparsemap_wrap(uint8_t *data, size_t size) { @@ -1008,13 +1025,24 @@ sparsemap_set_data_size(sparsemap_t *map, size_t size, uint8_t *data) /* Ensure that m_data is 8-byte aligned. */ size_t total_size = sizeof(sparsemap_t) + data_size; +#ifdef REENTRENT_SPARSEMAP + total_size += sizeof(pthread_mutex_t); +#endif size_t padding = total_size % 8 == 0 ? 0 : 8 - (total_size % 8); total_size += padding; +#ifdef REENTRENT_SPARSEMAP + sparsemap_t *rm = (sparsemap_t *)((uintptr_t)map - sizeof(pthread_mutex_t)); + sparsemap_t *m = (sparsemap_t *)realloc(rm, total_size); +#else sparsemap_t *m = (sparsemap_t *)realloc(map, total_size); +#endif if (!m) { return NULL; } +#ifdef REENTRENT_SPARSEMAP + sparsemap_t *m = (sparsemap_t *)((uintptr_t)m + sizeof(pthread_mutex_t)); +#endif memset(((uint8_t *)m) + sizeof(sparsemap_t) + (m->m_capacity * sizeof(uint8_t)), 0, size - m->m_capacity + padding); m->m_capacity = data_size; m->m_data = (uint8_t *)(((uintptr_t)m + sizeof(sparsemap_t)) & ~(uintptr_t)7); @@ -1028,6 +1056,18 @@ sparsemap_set_data_size(sparsemap_t *map, size_t size, uint8_t *data) } } +#ifdef REENTRENT_SPARSEMAP +sparsemap_t *sparsemap_set_data_size_r(sparsemap_t *map, size_t size, uint8_t *data) +{ + pthread_mutex_t *mutex = (pthread_mutex_t *)map; + sparsemap_t *rm = (sparsemap_t *)((uintptr_t)map + sizeof(pthread_mutex_t)); + pthread_mutex_lock(mutex); + sparsemap_t *ret = sparsemap_set_data_size(rm size, data); + pthread_mutex_unlock(mutex); + return ret; +} +#endif + double sparsemap_capacity_remaining(sparsemap_t *map) { diff --git a/tests/test.c b/tests/test.c index ffc7138..0c87e85 100644 --- a/tests/test.c +++ b/tests/test.c @@ -38,6 +38,10 @@ struct user_data { int foo; }; +#ifdef REENTRENT_SPARSEMAP +#define sparsemap() GSB +#endif + /* -------------------------- Supporting Functions for Testing */ void