tweak STBDS_REALLOC/STBDS_FREE change

This commit is contained in:
Sean Barrett 2019-06-17 05:25:44 -07:00
parent 258c6e1f50
commit 8f0bade4ae
1 changed files with 21 additions and 26 deletions

View File

@ -41,14 +41,15 @@ COMPILE-TIME OPTIONS
hash table insertion about 20% slower on 4- and 8-byte keys, 5% slower on hash table insertion about 20% slower on 4- and 8-byte keys, 5% slower on
64-byte keys, and 10% slower on 256-byte keys on my test computer. 64-byte keys, and 10% slower on 256-byte keys on my test computer.
#define STBDS_REALLOC better_realloc #define STBDS_REALLOC(context,ptr,size) better_realloc
#define STBDS_FREE better_free #define STBDS_FREE(context,ptr) better_free
These defines only need to be set in the file containing #define STB_DS_IMPLEMENTATION. These defines only need to be set in the file containing #define STB_DS_IMPLEMENTATION.
By default stb_ds uses stdlib realloc() and free() for memory management. You can By default stb_ds uses stdlib realloc() and free() for memory management. You can
substitute your own functions (with the same signatures) instead by defining these substitute your own functions instead by defining these symbols. You must either
symbols. You must either define both, or neither. define both, or neither. Note that at the moment, 'context' will always be NULL.
@TODO add an array/hash initialization function that takes a memory context pointer.
LICENSE LICENSE
@ -388,8 +389,8 @@ CREDITS
#endif #endif
#if !defined(STBDS_REALLOC) && !defined(STBDS_FREE) #if !defined(STBDS_REALLOC) && !defined(STBDS_FREE)
#include <stdlib.h> #include <stdlib.h>
#define STBDS_REALLOC realloc #define STBDS_REALLOC(c,p,s) realloc(p,s)
#define STBDS_FREE free #define STBDS_FREE(c,p) free(p)
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -423,7 +424,6 @@ extern void * stbds_hmput_default(void *a, size_t elemsize);
extern void * stbds_hmput_key(void *a, size_t elemsize, void *key, size_t keysize, int mode); extern void * stbds_hmput_key(void *a, size_t elemsize, void *key, size_t keysize, int mode);
extern void * stbds_hmdel_key(void *a, size_t elemsize, void *key, size_t keysize, size_t keyoffset, int mode); extern void * stbds_hmdel_key(void *a, size_t elemsize, void *key, size_t keysize, size_t keyoffset, int mode);
extern void * stbds_shmode_func(size_t elemsize, int mode); extern void * stbds_shmode_func(size_t elemsize, int mode);
extern void stbds_free(void *p);
#ifdef __cplusplus #ifdef __cplusplus
} }
@ -468,7 +468,7 @@ extern void stbds_free(void *p);
#define stbds_arrpop(a) (stbds_header(a)->length--, (a)[stbds_header(a)->length]) #define stbds_arrpop(a) (stbds_header(a)->length--, (a)[stbds_header(a)->length])
#define stbds_arraddn(a,n) (stbds_arrmaybegrow(a,n), stbds_header(a)->length += (n)) #define stbds_arraddn(a,n) (stbds_arrmaybegrow(a,n), stbds_header(a)->length += (n))
#define stbds_arrlast(a) ((a)[stbds_header(a)->length-1]) #define stbds_arrlast(a) ((a)[stbds_header(a)->length-1])
#define stbds_arrfree(a) ((void) ((a) ? stbds_free(stbds_header(a)) : (void)0), (a)=NULL) #define stbds_arrfree(a) ((void) ((a) ? STBDS_FREE(NULL,stbds_header(a)) : (void)0), (a)=NULL)
#define stbds_arrdel(a,i) stbds_arrdeln(a,i,1) #define stbds_arrdel(a,i) stbds_arrdeln(a,i,1)
#define stbds_arrdeln(a,i,n) (memmove(&(a)[i], &(a)[(i)+(n)], sizeof *(a) * (stbds_header(a)->length-(n)-(i))), stbds_header(a)->length -= (n)) #define stbds_arrdeln(a,i,n) (memmove(&(a)[i], &(a)[(i)+(n)], sizeof *(a) * (stbds_header(a)->length-(n)-(i))), stbds_header(a)->length -= (n))
#define stbds_arrdelswap(a,i) ((a)[i] = stbds_arrlast(a), stbds_header(a)->length -= 1) #define stbds_arrdelswap(a,i) ((a)[i] = stbds_arrlast(a), stbds_header(a)->length -= 1)
@ -642,11 +642,6 @@ size_t stbds_rehash_items;
#define STBDS_STATS(x) #define STBDS_STATS(x)
#endif #endif
void stbds_free(void *p)
{
STBDS_FREE(p);
}
// //
// stbds_arr implementation // stbds_arr implementation
// //
@ -669,7 +664,7 @@ void *stbds_arrgrowf(void *a, size_t elemsize, size_t addlen, size_t min_cap)
else if (min_cap < 4) else if (min_cap < 4)
min_cap = 4; min_cap = 4;
b = STBDS_REALLOC((a) ? stbds_header(a) : 0, elemsize * min_cap + sizeof(stbds_array_header)); b = STBDS_REALLOC(NULL, (a) ? stbds_header(a) : 0, elemsize * min_cap + sizeof(stbds_array_header));
b = (char *) b + sizeof(stbds_array_header); b = (char *) b + sizeof(stbds_array_header);
if (a == NULL) { if (a == NULL) {
stbds_header(b)->length = 0; stbds_header(b)->length = 0;
@ -761,7 +756,7 @@ static size_t stbds_log2(size_t slot_count)
static stbds_hash_index *stbds_make_hash_index(size_t slot_count, stbds_hash_index *ot) static stbds_hash_index *stbds_make_hash_index(size_t slot_count, stbds_hash_index *ot)
{ {
stbds_hash_index *t; stbds_hash_index *t;
t = (stbds_hash_index *) STBDS_REALLOC(0,(slot_count >> STBDS_BUCKET_SHIFT) * sizeof(stbds_hash_bucket) + sizeof(stbds_hash_index) + STBDS_CACHE_LINE_SIZE-1); t = (stbds_hash_index *) STBDS_REALLOC(NULL,0,(slot_count >> STBDS_BUCKET_SHIFT) * sizeof(stbds_hash_bucket) + sizeof(stbds_hash_index) + STBDS_CACHE_LINE_SIZE-1);
t->storage = (stbds_hash_bucket *) STBDS_ALIGN_FWD((size_t) (t+1), STBDS_CACHE_LINE_SIZE); t->storage = (stbds_hash_bucket *) STBDS_ALIGN_FWD((size_t) (t+1), STBDS_CACHE_LINE_SIZE);
t->slot_count = slot_count; t->slot_count = slot_count;
t->slot_count_log2 = stbds_log2(slot_count); t->slot_count_log2 = stbds_log2(slot_count);
@ -1088,12 +1083,12 @@ void stbds_hmfree_func(void *a, size_t elemsize, size_t keyoff)
size_t i; size_t i;
// skip 0th element, which is default // skip 0th element, which is default
for (i=1; i < stbds_header(a)->length; ++i) for (i=1; i < stbds_header(a)->length; ++i)
STBDS_FREE(*(char**) ((char *) a + elemsize*i)); STBDS_FREE(NULL, *(char**) ((char *) a + elemsize*i));
} }
stbds_strreset(&stbds_hash_table(a)->string); stbds_strreset(&stbds_hash_table(a)->string);
} }
STBDS_FREE(stbds_header(a)->hash_table); STBDS_FREE(NULL, stbds_header(a)->hash_table);
STBDS_FREE(stbds_header(a)); STBDS_FREE(NULL, stbds_header(a));
} }
static ptrdiff_t stbds_hm_find_slot(void *a, size_t elemsize, void *key, size_t keysize, int mode) static ptrdiff_t stbds_hm_find_slot(void *a, size_t elemsize, void *key, size_t keysize, int mode)
@ -1219,7 +1214,7 @@ void *stbds_hmput_key(void *a, size_t elemsize, void *key, size_t keysize, int m
slot_count = (table == NULL) ? STBDS_BUCKET_LENGTH : table->slot_count*2; slot_count = (table == NULL) ? STBDS_BUCKET_LENGTH : table->slot_count*2;
nt = stbds_make_hash_index(slot_count, table); nt = stbds_make_hash_index(slot_count, table);
if (table) { if (table) {
STBDS_FREE(table); STBDS_FREE(NULL, table);
} }
stbds_header(a)->hash_table = table = nt; stbds_header(a)->hash_table = table = nt;
STBDS_STATS(++stbds_hash_grow); STBDS_STATS(++stbds_hash_grow);
@ -1354,7 +1349,7 @@ void * stbds_hmdel_key(void *a, size_t elemsize, void *key, size_t keysize, size
b->index[i] = STBDS_INDEX_DELETED; b->index[i] = STBDS_INDEX_DELETED;
if (mode == STBDS_HM_STRING && table->string.mode == STBDS_SH_STRDUP) if (mode == STBDS_HM_STRING && table->string.mode == STBDS_SH_STRDUP)
STBDS_FREE(*(char**) ((char *) a+elemsize*old_index)); STBDS_FREE(NULL, *(char**) ((char *) a+elemsize*old_index));
// if indices are the same, memcpy is a no-op, but back-pointer-fixup will fail, so skip // if indices are the same, memcpy is a no-op, but back-pointer-fixup will fail, so skip
if (old_index != final_index) { if (old_index != final_index) {
@ -1376,11 +1371,11 @@ void * stbds_hmdel_key(void *a, size_t elemsize, void *key, size_t keysize, size
if (table->used_count < table->used_count_shrink_threshold && table->slot_count > STBDS_BUCKET_LENGTH) { if (table->used_count < table->used_count_shrink_threshold && table->slot_count > STBDS_BUCKET_LENGTH) {
stbds_header(raw_a)->hash_table = stbds_make_hash_index(table->slot_count>>1, table); stbds_header(raw_a)->hash_table = stbds_make_hash_index(table->slot_count>>1, table);
STBDS_FREE(table); STBDS_FREE(NULL, table);
STBDS_STATS(++stbds_hash_shrink); STBDS_STATS(++stbds_hash_shrink);
} else if (table->tombstone_count > table->tombstone_count_threshold) { } else if (table->tombstone_count > table->tombstone_count_threshold) {
stbds_header(raw_a)->hash_table = stbds_make_hash_index(table->slot_count , table); stbds_header(raw_a)->hash_table = stbds_make_hash_index(table->slot_count , table);
STBDS_FREE(table); STBDS_FREE(NULL, table);
STBDS_STATS(++stbds_hash_rebuild); STBDS_STATS(++stbds_hash_rebuild);
} }
@ -1397,7 +1392,7 @@ static char *stbds_strdup(char *str)
// to keep replaceable allocator simple, we don't want to use strdup. // to keep replaceable allocator simple, we don't want to use strdup.
// rolling our own also avoids problem of strdup vs _strdup // rolling our own also avoids problem of strdup vs _strdup
size_t len = strlen(str)+1; size_t len = strlen(str)+1;
char *p = (char*) STBDS_REALLOC(0, len); char *p = (char*) STBDS_REALLOC(NULL, 0, len);
memmove(p, str, len); memmove(p, str, len);
return p; return p;
} }
@ -1430,7 +1425,7 @@ char *stbds_stralloc(stbds_string_arena *a, char *str)
// note that we still advance string_block so block size will continue // note that we still advance string_block so block size will continue
// increasing, so e.g. if somebody only calls this with 1000-long strings, // increasing, so e.g. if somebody only calls this with 1000-long strings,
// eventually the arena will start doubling and handling those as well // eventually the arena will start doubling and handling those as well
stbds_string_block *sb = (stbds_string_block *) STBDS_REALLOC(0, sizeof(*sb)-8 + len); stbds_string_block *sb = (stbds_string_block *) STBDS_REALLOC(NULL, 0, sizeof(*sb)-8 + len);
memmove(sb->storage, str, len); memmove(sb->storage, str, len);
if (a->storage) { if (a->storage) {
// insert it after the first element, so that we don't waste the space there // insert it after the first element, so that we don't waste the space there
@ -1443,7 +1438,7 @@ char *stbds_stralloc(stbds_string_arena *a, char *str)
} }
return sb->storage; return sb->storage;
} else { } else {
stbds_string_block *sb = (stbds_string_block *) STBDS_REALLOC(0, sizeof(*sb)-8 + blocksize); stbds_string_block *sb = (stbds_string_block *) STBDS_REALLOC(NULL, 0, sizeof(*sb)-8 + blocksize);
sb->next = a->storage; sb->next = a->storage;
a->storage = sb; a->storage = sb;
a->remaining = blocksize; a->remaining = blocksize;
@ -1463,7 +1458,7 @@ void stbds_strreset(stbds_string_arena *a)
x = a->storage; x = a->storage;
while (x) { while (x) {
y = x->next; y = x->next;
STBDS_FREE(x); STBDS_FREE(NULL, x);
x = y; x = y;
} }
memset(a, 0, sizeof(*a)); memset(a, 0, sizeof(*a));