WIP: gburd/thread-safe #7
4 changed files with 54 additions and 4 deletions
8
Makefile
8
Makefile
|
@ -5,16 +5,16 @@ SHARED_LIB = libsparsemap.so
|
||||||
|
|
||||||
#CFLAGS = -Wall -Wextra -Wpedantic -Of -std=c11 -Iinclude/ -fPIC
|
#CFLAGS = -Wall -Wextra -Wpedantic -Of -std=c11 -Iinclude/ -fPIC
|
||||||
#CFLAGS = -Wall -Wextra -Wpedantic -Og -g -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 -D_FORTIFY_SOURCE=0 -O0 -g -std=c11 -Iinclude/ -fPIC
|
||||||
CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -Ofast -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 -Og -g -std=c11 -Iinclude/ -fPIC
|
||||||
#CFLAGS = -Wall -Wextra -Wpedantic -Ofast -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 = -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
|
#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 -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
|
#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
|
TESTS = tests/test
|
||||||
|
|
|
@ -109,6 +109,9 @@ typedef uint64_t sm_bitvec_t;
|
||||||
* @returns The newly allocated sparsemap reference.
|
* @returns The newly allocated sparsemap reference.
|
||||||
*/
|
*/
|
||||||
sparsemap_t *sparsemap(size_t size);
|
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
|
/** @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.
|
* \b data of \b size bytes to use for storage of bitmap data.
|
||||||
|
@ -190,6 +193,9 @@ void sparsemap_clear(sparsemap_t *map);
|
||||||
* supported.
|
* supported.
|
||||||
*/
|
*/
|
||||||
sparsemap_t *sparsemap_set_data_size(sparsemap_t *map, size_t size, uint8_t *data);
|
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.
|
/** @brief Calculate remaining capacity, approaches 0 when full.
|
||||||
*
|
*
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifdef REENTRENT_SPARSEMAP
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SPARSEMAP_DIAGNOSTIC
|
#ifdef SPARSEMAP_DIAGNOSTIC
|
||||||
#pragma GCC diagnostic push
|
#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)
|
#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 {
|
typedef struct {
|
||||||
sm_bitvec_t *m_data;
|
sm_bitvec_t *m_data;
|
||||||
|
@ -966,6 +970,19 @@ sparsemap(size_t size)
|
||||||
return map;
|
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_t *
|
||||||
sparsemap_wrap(uint8_t *data, size_t size)
|
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. */
|
/* Ensure that m_data is 8-byte aligned. */
|
||||||
size_t total_size = sizeof(sparsemap_t) + data_size;
|
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);
|
size_t padding = total_size % 8 == 0 ? 0 : 8 - (total_size % 8);
|
||||||
total_size += padding;
|
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);
|
sparsemap_t *m = (sparsemap_t *)realloc(map, total_size);
|
||||||
|
#endif
|
||||||
if (!m) {
|
if (!m) {
|
||||||
return NULL;
|
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);
|
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_capacity = data_size;
|
||||||
m->m_data = (uint8_t *)(((uintptr_t)m + sizeof(sparsemap_t)) & ~(uintptr_t)7);
|
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
|
double
|
||||||
sparsemap_capacity_remaining(sparsemap_t *map)
|
sparsemap_capacity_remaining(sparsemap_t *map)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,6 +38,10 @@ struct user_data {
|
||||||
int foo;
|
int foo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef REENTRENT_SPARSEMAP
|
||||||
|
#define sparsemap() GSB
|
||||||
|
#endif
|
||||||
|
|
||||||
/* -------------------------- Supporting Functions for Testing */
|
/* -------------------------- Supporting Functions for Testing */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue