diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-06-02 12:55:39 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-06-03 13:55:33 -0400 |
| commit | a9a0920f431c76f31157edd42c6d055b673ed12f (patch) | |
| tree | 8884ae8cd6de5d896dfd54efe1539a33e6ce2b6e | |
| parent | 467dce9c254737e8437735471af887a544ef8d10 (diff) | |
pkfuncinstr.h: created, first-pass
| -rw-r--r-- | Makefile | 14 | ||||
| -rw-r--r-- | config.mk | 29 | ||||
| -rw-r--r-- | pk.h.in | 50 | ||||
| -rw-r--r-- | pkfuncinstr.h | 311 | ||||
| -rw-r--r-- | test/pkmem.c | 13 | ||||
| -rw-r--r-- | test/pkmem.cpp | 313 | ||||
| -rw-r--r-- | test/pkuuid.c | 7 |
7 files changed, 570 insertions, 167 deletions
@@ -16,6 +16,7 @@ SRC = \ pkuuid.h \ pkbktarr.h \ pktmpln.h \ + pkfuncinstr.h \ test/pkmacros.c \ test/pkmacros.cpp \ test/pkmem-types.c \ @@ -54,6 +55,7 @@ all: options .WAIT clean .WAIT \ pkuuid \ pkbktarr \ pktmpln \ + pkfuncinstr \ test/test-pkmem-types test/test-pkmem-types-cpp \ test/test-pkmem test/test-pkmem-cpp \ test/test-pkmacros test/test-pkmacros-cpp \ @@ -74,9 +76,9 @@ options: @echo "CXX = $(CXX)" %.gch: %.h - $(CC) -std=c2x $(CFLAGS) -c $< -o $@ + $(CC) -std=c2x $(CFLAGS) $(OPTLEVEL) -c $< -o $@ %.gchpp: %.h - $(CXX) -std=c++23 $(CXXFLAGS) -x c++-header -c $< -o $@ + $(CXX) -std=c++23 $(CXXFLAGS) $(OPTLEVEL) -x c++-header -c $< -o $@ %.o: %.c $(CC) -std=c2x $(CFLAGS) -g $(OPTLEVEL) -c $< -o $@ %.so: %.cpp @@ -109,6 +111,8 @@ pkbktarr: pkbktarr.gch pkbktarr.gchpp pktmpln: pktmpln.gch pktmpln.gchpp +pkfuncinstr: pkfuncinstr.gch pkfuncinstr.gchpp + build: pkmacros build: pkmem-types build: pkmem @@ -119,9 +123,11 @@ build: pkstn build: pktmr build: pkuuid build: pkbktarr +build: pkfuncinstr echo "#ifndef PK_SINGLE_HEADER_FILE_H\n#define PK_SINGLE_HEADER_FILE_H" > pk.h cat pk.h.in \ pkmacros.h \ + pktmpln.h \ pkmem-types.h \ pkmem.h \ pkstr.h \ @@ -131,7 +137,7 @@ build: pkbktarr pktmr.h \ pkuuid.h \ pkbktarr.h \ - pktmpln.h \ + pkfuncinstr.h \ >> pk.h echo "#endif /* PK_SINGLE_HEADER_FILE_H */" >> pk.h sed -i -r \ @@ -202,6 +208,7 @@ test/test-pkbktarr: test/pkbktarr.o test/test-pkbktarr-cpp: test/pkbktarr.so $(CXX) -g $(OPTLEVEL) -std=c++23 $(CXXFLAGS) -o $@ $^ $(LDFLAGS) +test: options test: pkmacros test/test-pkmacros test/test-pkmacros-cpp test: pkmem-types test/test-pkmem-types test/test-pkmem-types-cpp test: pkmem test/test-pkmem test/test-pkmem-cpp @@ -213,6 +220,7 @@ test: pktmr test/test-pktmr test/test-pktmr-cpp test: pkuuid test/test-pkuuid test/test-pkuuid-cpp test: pkbktarr test/test-pkbktarr test/test-pkbktarr-cpp test: pktmpln +test: pkfuncinstr test: @echo "" ./test/test-pkmacros ; echo Result: $$? "\n" @@ -7,22 +7,35 @@ MANPREFIX = $(PREFIX)/share/man PKG_CONFIG = pkg-config +# compiler and linker +CC ?= /usr/bin/gcc +CXX ?= /usr/bin/g++ + # includes and libs INCS = \ +# dl is for pkfuncinstr LIBS = -lm \ + -ldl \ # flags -# -pedantic +# -rdynamic is for pkfuncinstr SHARED_FLAGS = -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L \ - -DVERSION=\"$(VERSION)\" -DPK_MEMORY_DEBUGGER -DPK_IMPL_ALL \ + -DVERSION=\"$(VERSION)\" \ + -DPK_MEMORY_DEBUGGER \ + -pedantic \ + -rdynamic \ -CFLAGS += -Wall -Wextra -pedantic $(INCS) $(SHARED_FLAGS) -CXXFLAGS += -Wall -Wextra -pedantic $(INCS) $(SHARED_FLAGS) +CFLAGS += -Wall -Wextra $(INCS) $(SHARED_FLAGS) +CXXFLAGS += -Wall -Wextra $(INCS) $(SHARED_FLAGS) LDFLAGS = $(LIBS) -OPTLEVEL ?= -O3 +# -finstrument-functions is for pkfuncinstr +ifeq ($(CC),/usr/bin/gcc) + CFLAGS += -finstrument-functions +endif +ifeq ($(CXX),/usr/bin/g++) + CXXFLAGS += -finstrument-functions +endif -# compiler and linker -CC ?= /usr/bin/gcc -CXX ?= /usr/bin/g++ +OPTLEVEL ?= -O3 @@ -46,6 +46,27 @@ * type-specific integers, implemented via enums. * ******************************************************************************** +* pktmpl.h: only contains c++ templates, no IMPL. +* +* Provides template structs for trampolines, allowing c-style callbacks with +* capturing lambdas. +* +* Examples: +* ```c++ +* int some_counter = 0; +* using IterCbWrapper = pk_tmpln_1<void, int*, void*>; +* IterCbWrapper cb_wrapper{}; +* cb_wrapper.func = [&some_counter](int *lhs) +* { +* (void)lhs; +* some_counter += 1; +* return; +* }; +* pk_bkt_arr_iterate(&bkt_arr, &IterCbWrapper::invoke, &cb_wrapper); +* assert(some_count == 1); +* ``` +* +******************************************************************************** * pkmem-types.h: def PK_IMPL_MEM_TYPES before including pk.h to enable ad-hoc. * * Provides the types needed by pkmem, as well as a generic pk_handle featuring a @@ -252,24 +273,20 @@ * ``` * ******************************************************************************** -* pktmpl.h: only contains c++ templates, no IMPL. +* pkbktarr.h: define PK_IMPL_FUNCINSTR before including pk.h to enable ad-hoc. * -* Provides template structs for trampolines, allowing c-style callbacks with -* capturing lambdas. +* Provides function instrumentation. +* +* Note: Currently only supports gcc/g++. +* Note: Currently only prints results. * * Examples: -* ```c++ -* int some_counter = 0; -* using IterCbWrapper = pk_tmpln_1<void, int*, void*>; -* IterCbWrapper cb_wrapper{}; -* cb_wrapper.func = [&some_counter](int *lhs) -* { -* (void)lhs; -* some_counter += 1; -* return; -* }; -* pk_bkt_arr_iterate(&bkt_arr, &IterCbWrapper::invoke, &cb_wrapper); -* assert(some_count == 1); +* ```c +* main() { +* pk_funcinstr_init(); +* ... +* pk_funcinstr_teardown(); +* } * ``` * *******************************************************************************/ @@ -301,4 +318,7 @@ # ifndef PK_IMPL_BKTARR # define PK_IMPL_BKTARR # endif +# ifndef PK_IMPL_FUNCINSTR +# define PK_IMPL_FUNCINSTR +# endif #endif diff --git a/pkfuncinstr.h b/pkfuncinstr.h new file mode 100644 index 0000000..0f76eed --- /dev/null +++ b/pkfuncinstr.h @@ -0,0 +1,311 @@ +#ifndef PK_PKFUNCINSTR_H +#define PK_PKFUNCINSTR_H + +#include "./pktmr.h" /* deleteme */ + +#define PK_FUNCINSTR_CHILDREN_INCREMENT_COUNT 8 + +struct pk_funcinstr; +struct pk_funcinstr { + void *fn; + struct pk_tmr tmr; + struct pk_funcinstr *parent; + struct pk_funcinstr *first_child; + struct pk_funcinstr **children; + size_t n_children; + size_t r_children; +}; + +void pk_funcinstr_init(); +void pk_funcinstr_teardown(); + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(__clang__) +// clang +#elif defined(__GNUC__) || defined(__GNUG__) + +void __cyg_profile_func_enter(void* this_fn, void* call_site); +void __cyg_profile_func_exit(void* this_fn, void* call_site); + +#else +// other +#endif + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif /* PK_PKFUNCINSTR_H */ +#if defined(PK_IMPL_FUNCINSTR) + +#include <assert.h> +#include <stdio.h> +#include <threads.h> +#include <string.h> + +// TODO 2025-06-02 JCB +// There's some speed improvements that can be made here by growing faster. +// OR use some type of bucket +// - might be a good chance to isolate some of the pkmem logic + +#define PK_FUNCINSTR_BKT_START_COUNT 4 +#define PK_FUNCINSTR_BKT_GROW_AMOUNT 4 +#define PK_FUNCINSTR_BKT_DATA_COUNT 255 +struct pk_funcinstr_bkt { + uint8_t used_count; + uint8_t guard_enter; + uint8_t guard_exit; + struct timespec reset_time; + struct pk_funcinstr data[PK_FUNCINSTR_BKT_DATA_COUNT+1]; +}; +struct pk_funcinstr_mstr { + mtx_t mtx; + struct timespec reset_time; + struct pk_funcinstr_bkt **buckets; + size_t r_buckets; + size_t n_buckets; +}; +// if NULL, get a new bucket (or alloc if full). if !NULL, existing thread +static thread_local struct pk_funcinstr_bkt *pk_funcinstr_thrd_bkt = NULL; +// last function call (should be NULL or parent of current) +static thread_local struct pk_funcinstr *pk_funcinstr_thrd_instr = NULL; +static struct pk_funcinstr_mstr thrd_mstr; + +__attribute__((no_instrument_function)) +void pk_funcinstr_init() { + assert(thrd_mstr.reset_time.tv_sec == 0); + assert(thrd_mstr.reset_time.tv_nsec == 0); + assert(thrd_mstr.buckets == NULL); + assert(thrd_mstr.r_buckets == 0); + assert(thrd_mstr.n_buckets == 0); + mtx_init(&thrd_mstr.mtx, mtx_plain); + thrd_mstr.r_buckets = PK_FUNCINSTR_BKT_START_COUNT; + thrd_mstr.buckets = (struct pk_funcinstr_bkt**)aligned_alloc(alignof(struct pk_funcinstr_bkt *), (sizeof(struct pk_funcinstr_bkt *) * PK_FUNCINSTR_BKT_START_COUNT)); + memset(thrd_mstr.buckets, 0, (sizeof(struct pk_funcinstr_bkt *) * PK_FUNCINSTR_BKT_START_COUNT)); + clock_gettime(PK_TMR_CLOCK, &thrd_mstr.reset_time); +} + +__attribute__((no_instrument_function)) +void pk_funcinstr_teardown() { + size_t i, k; + mtx_lock(&thrd_mstr.mtx); + for (i = 0; i < thrd_mstr.n_buckets; ++i) { + struct pk_funcinstr_bkt *bkt = thrd_mstr.buckets[i]; + for (k = 0; k < bkt->used_count; ++k) { + free(bkt->data[k].children); + } + } + free(thrd_mstr.buckets); + thrd_mstr.reset_time.tv_sec = 0; + thrd_mstr.reset_time.tv_nsec = 0; + thrd_mstr.buckets = NULL; + thrd_mstr.r_buckets = 0; + thrd_mstr.n_buckets = 0; + mtx_unlock(&thrd_mstr.mtx); + mtx_destroy(&thrd_mstr.mtx); +} + +#if defined(__clang__) +// TODO clang XRay +// Come up with pk macros since XRay requires attributes to instrument? +#elif defined(__GNUC__) || defined(__GNUG__) + +#ifndef __USE_GNU + #define __USE_GNU +#endif +#if defined(__cplusplus) +#include <cxxabi.h> +#endif +#include <dlfcn.h> +#include <link.h> +#include <string.h> + +__attribute__((no_instrument_function)) +bool pk_funcinstr_detect_not_initialized() { + if (thrd_mstr.buckets == NULL) return true; + if (thrd_mstr.r_buckets == 0) return true; + return false; +} + +__attribute__((no_instrument_function)) +void pk_funcinstr_detect_and_handle_reset() { + bool should_hard_reset = false; + bool should_reset = pk_funcinstr_thrd_bkt == NULL; + if (pk_funcinstr_thrd_bkt != NULL) { + should_reset = pk_funcinstr_thrd_bkt->used_count == PK_FUNCINSTR_BKT_DATA_COUNT; + should_hard_reset = thrd_mstr.reset_time.tv_sec > pk_funcinstr_thrd_bkt->reset_time.tv_sec; + should_hard_reset = should_hard_reset || (thrd_mstr.reset_time.tv_sec == pk_funcinstr_thrd_bkt->reset_time.tv_sec && thrd_mstr.reset_time.tv_nsec > pk_funcinstr_thrd_bkt->reset_time.tv_nsec); + } + if (should_hard_reset) { + pk_funcinstr_thrd_bkt = NULL; + pk_funcinstr_thrd_instr = NULL; + should_reset = true; + } + if (should_reset) { + if (thrd_mstr.n_buckets == thrd_mstr.r_buckets) { + mtx_lock(&thrd_mstr.mtx); + thrd_mstr.r_buckets += PK_FUNCINSTR_BKT_GROW_AMOUNT; + struct pk_funcinstr_bkt **buckets = (struct pk_funcinstr_bkt**)aligned_alloc(alignof(void *), sizeof(void *) * thrd_mstr.r_buckets); + memcpy(buckets, thrd_mstr.buckets, sizeof(void *) * (thrd_mstr.n_buckets)); + memset((char*)buckets + (sizeof(void *) * (thrd_mstr.n_buckets)), 0, (sizeof(void *) * thrd_mstr.r_buckets) - sizeof(void *) * (thrd_mstr.n_buckets)); + free(thrd_mstr.buckets); + thrd_mstr.buckets = buckets; + mtx_unlock(&thrd_mstr.mtx); + } + struct pk_funcinstr_bkt *bkt = (struct pk_funcinstr_bkt *)aligned_alloc(alignof(struct pk_funcinstr_bkt), sizeof(struct pk_funcinstr_bkt)); + bkt->used_count = 0; + bkt->guard_enter = 0; + bkt->guard_exit = 0; + bkt->reset_time.tv_sec = 0; + bkt->reset_time.tv_nsec = 0; + if (pk_funcinstr_thrd_bkt != NULL) { + pk_funcinstr_thrd_bkt->guard_enter = 0; + pk_funcinstr_thrd_bkt->guard_exit = 0; + } + pk_funcinstr_thrd_bkt = bkt; + mtx_lock(&thrd_mstr.mtx); + thrd_mstr.buckets[thrd_mstr.n_buckets++] = bkt; + mtx_unlock(&thrd_mstr.mtx); + clock_gettime(PK_TMR_CLOCK, &pk_funcinstr_thrd_bkt->reset_time); + } +} + +__attribute__((no_instrument_function)) +bool pk_funcinstr_should_early_exit() { + if (pk_funcinstr_thrd_bkt->guard_enter != 0) return true; + if (pk_funcinstr_thrd_bkt->guard_exit != 0) return true; + return false; +} + +__attribute__((no_instrument_function)) +struct pk_funcinstr *pk_funcinstr_create_funcinstr(void *this_fn) { + struct pk_funcinstr *funcinstr = &pk_funcinstr_thrd_bkt->data[pk_funcinstr_thrd_bkt->used_count]; + pk_funcinstr_thrd_bkt->used_count++; + pk_tmr_start(funcinstr->tmr); + funcinstr->fn = this_fn; + funcinstr->parent = pk_funcinstr_thrd_instr; + funcinstr->children = NULL; + funcinstr->first_child = NULL; + funcinstr->n_children = 0; + funcinstr->r_children = 0; + + if (pk_funcinstr_thrd_instr != NULL) { + if (pk_funcinstr_thrd_instr->first_child == NULL) { + // avoid an malloc if n_children will only == 1 + pk_funcinstr_thrd_instr->first_child = funcinstr; + } else { + if (pk_funcinstr_thrd_instr->n_children == pk_funcinstr_thrd_instr->r_children) { + pk_funcinstr_thrd_instr->r_children += PK_FUNCINSTR_CHILDREN_INCREMENT_COUNT; + struct pk_funcinstr **children = (struct pk_funcinstr **)aligned_alloc(alignof(void *), sizeof(void *) * pk_funcinstr_thrd_instr->r_children); + memset((char*)children + (sizeof(void *) * (pk_funcinstr_thrd_instr->n_children)), 0, (sizeof(void *) * pk_funcinstr_thrd_instr->r_children) - sizeof(void *) * (pk_funcinstr_thrd_instr->n_children)); + if (pk_funcinstr_thrd_instr->children != NULL) { + memcpy(children, pk_funcinstr_thrd_instr->children, sizeof(void *) * pk_funcinstr_thrd_instr->n_children); + free(pk_funcinstr_thrd_instr->children); + } + pk_funcinstr_thrd_instr->children = children; + if (pk_funcinstr_thrd_instr->n_children == 0) { + pk_funcinstr_thrd_instr->children[0] = pk_funcinstr_thrd_instr->first_child; + pk_funcinstr_thrd_instr->n_children++; + } + } + pk_funcinstr_thrd_instr->children[pk_funcinstr_thrd_instr->n_children] = funcinstr; + pk_funcinstr_thrd_instr->n_children++; + } + } + return funcinstr; +} + +__attribute__((no_instrument_function)) +void __cyg_profile_func_enter(void* this_fn, void* call_site) { + (void)call_site; + if (pk_funcinstr_detect_not_initialized()) return; + pk_funcinstr_detect_and_handle_reset(); + if (pk_funcinstr_should_early_exit()) return; + pk_funcinstr_thrd_bkt->guard_enter++; + + pk_funcinstr_thrd_instr = pk_funcinstr_create_funcinstr(this_fn); + + pk_funcinstr_thrd_bkt->guard_enter = 0; +} + +__attribute__((no_instrument_function)) +void __cyg_profile_func_exit(void* this_fn, void* call_site) { + (void)call_site; + if (pk_funcinstr_detect_not_initialized()) return; + pk_funcinstr_detect_and_handle_reset(); + if (pk_funcinstr_should_early_exit()) return; + if (pk_funcinstr_thrd_instr == NULL) return; // exit called before enter? + pk_funcinstr_thrd_bkt->guard_exit++; + + Dl_info info; + + if (this_fn != pk_funcinstr_thrd_instr->fn) { + int64_t i = (int64_t)pk_funcinstr_thrd_bkt->used_count - 1; + for (; i > -1; --i) { + if (pk_funcinstr_thrd_bkt->data[i].fn == this_fn) { + if (pk_funcinstr_thrd_bkt->data[i].tmr.e.tv_sec == 0) { + pk_funcinstr_thrd_instr = &pk_funcinstr_thrd_bkt->data[i]; + break; + } + } + } + } + if (this_fn != pk_funcinstr_thrd_instr->fn) { + if (pk_funcinstr_thrd_instr->parent == NULL) { + struct pk_tmr tmr = pk_funcinstr_thrd_instr->tmr; + pk_funcinstr_thrd_instr = pk_funcinstr_create_funcinstr(this_fn); + pk_funcinstr_thrd_instr->tmr = tmr; + fprintf(stdout, "[pkfuncinstr] func mismatch; Parent func? Duration not accurate."); + } else { + fprintf(stderr, "[pkfuncinstr] func mismatch. Last: '"); + if (dladdr(pk_funcinstr_thrd_instr->fn, &info) != 0) { + fprintf(stderr, "%s", info.dli_sname); + } else { + fprintf(stderr, "(unknown)"); + } + fprintf(stderr, "'. Current: '"); + if (dladdr(this_fn, &info) != 0) { + fprintf(stderr, "%s'.\n", info.dli_sname); + } else { + fprintf(stderr, "(unknown)'.\n"); + } + pk_funcinstr_thrd_bkt->guard_exit=0; + return; + } + } + + pk_tmr_stop(pk_funcinstr_thrd_instr->tmr); + if (dladdr(this_fn, &info) != 0) { + int depth = 0; + // TODO track depth in a better way + struct pk_funcinstr *p = pk_funcinstr_thrd_instr->parent; + while (p != NULL) { + depth += 1; + p = p->parent; + } + char *demangled = NULL; + if (info.dli_sname != NULL) { +#if defined(__cplusplus) + demangled = abi::__cxa_demangle(info.dli_sname, NULL, NULL, NULL); +#endif + } + fprintf(stdout, "[pkfuncinstr] %p %*s %s took %.6f ms\n" + ,this_fn + ,depth, "" + ,demangled != NULL ? demangled : info.dli_sname != NULL ? info.dli_sname : "???" + ,pk_tmr_duration_dbl_mili(pk_funcinstr_thrd_instr->tmr) + ); + if (demangled != NULL) free(demangled); + } + pk_funcinstr_thrd_bkt->guard_exit=0; + pk_funcinstr_thrd_instr = pk_funcinstr_thrd_instr->parent; +} + +#else +// other +#endif + +#endif /* PK_IMPL_FUNCINSTR */ diff --git a/test/pkmem.c b/test/pkmem.c index 78ea796..252428d 100644 --- a/test/pkmem.c +++ b/test/pkmem.c @@ -3,6 +3,9 @@ #include "../pkmem.h" +#define PK_IMPL_FUNCINSTR +#include "../pkfuncinstr.h" + #include <stdio.h> #include <string.h> @@ -16,9 +19,15 @@ void spinup() { mt.bkt2 = pk_bucket_create("bkt2", 1024, false); } +void spinup_w_instr() { + pk_funcinstr_init(); + spinup(); +} + void teardown() { pk_bucket_destroy(mt.bkt1); pk_bucket_destroy(mt.bkt2); + pk_funcinstr_teardown(); } int main(int argc, char *argv[]) @@ -28,7 +37,7 @@ int main(int argc, char *argv[]) // pk_new_base { - spinup(); + spinup_w_instr(); char *some_dang_string = (char*)pk_new_base(64, alignof(char*)); fprintf(stdout, "some_dang_string: %s: %p\n", some_dang_string, (void *)some_dang_string); pk_delete_base(some_dang_string, 64); @@ -44,7 +53,7 @@ int main(int argc, char *argv[]) // zero-length alloc { - spinup(); + spinup_w_instr(); char *zero_length_string; char *three_length_string; diff --git a/test/pkmem.cpp b/test/pkmem.cpp index 1a6dd8f..98d2dd2 100644 --- a/test/pkmem.cpp +++ b/test/pkmem.cpp @@ -3,7 +3,14 @@ #include "../pkmem.h" -#include <new> +#define PK_IMPL_FUNCINSTR +#include "../pkfuncinstr.h" + +#ifndef PK_MEMORY_FORCE_MALLOC + #define pk_mem_assert(expr) assert(expr) +#else + #define pk_mem_assert(expr) (void)0; +#endif class FreeTest { public: @@ -48,12 +55,12 @@ class FreeTest01 : public FreeTest { virtual ~FreeTest01() {} virtual void ensureState() override { - assert(3 == bkt->lastEmptyBlockIndex); - assert(80 == bkt->head); - assert(bkt->ptr + 00 == ptrs[0]); - assert(bkt->ptr + 64 == ptrs[1]); - assert(bkt->ptr + 16 == ptrs[2]); - assert(bkt->ptr + 8 == ptrs[3]); + pk_mem_assert(3 == bkt->lastEmptyBlockIndex); + pk_mem_assert(80 == bkt->head); + pk_mem_assert(bkt->ptr + 00 == ptrs[0]); + pk_mem_assert(bkt->ptr + 64 == ptrs[1]); + pk_mem_assert(bkt->ptr + 16 == ptrs[2]); + pk_mem_assert(bkt->ptr + 8 == ptrs[3]); } }; @@ -82,20 +89,21 @@ class FreeTest02 : public FreeTest { virtual ~FreeTest02() {} virtual void ensureState() override { - assert(2 == bkt->lastEmptyBlockIndex); - assert(65 == bkt->head); - assert(bkt->ptr + 00 == ptrs[0]); - assert(bkt->ptr + 64 == ptrs[1]); - assert(bkt->ptr + 32 == ptrs[2]); + pk_mem_assert(2 == bkt->lastEmptyBlockIndex); + pk_mem_assert(65 == bkt->head); + pk_mem_assert(bkt->ptr + 00 == ptrs[0]); + pk_mem_assert(bkt->ptr + 64 == ptrs[1]); + pk_mem_assert(bkt->ptr + 32 == ptrs[2]); - assert(bkt->ptr + 19 == bkt->blocks[0].data); - assert(13 == bkt->blocks[0].size); + pk_mem_assert(bkt->ptr + 19 == bkt->blocks[0].data); + pk_mem_assert(13 == bkt->blocks[0].size); - assert(bkt->ptr + 33 == bkt->blocks[1].data); - assert(31 == bkt->blocks[1].size); + pk_mem_assert(bkt->ptr + 33 == bkt->blocks[1].data); + pk_mem_assert(31 == bkt->blocks[1].size); } }; +const char *test_basic_alloc = "test_basic_alloc"; const char *test_misalignment01 = "test_misalignment01"; const char *test_misalignment02 = "test_misalignment02"; const char *test_free_0000 = "test_free_0000"; @@ -113,6 +121,14 @@ const char *test_bucket_count03 = "test_bucket_count03"; const char *test_bucket_count04 = "test_bucket_count04"; const char *test_bucket_count05 = "test_bucket_count05"; +void pk_test_pkmem_spinup(bool init_funcinstr = false) { + if (init_funcinstr) pk_funcinstr_init(); +} +void pk_test_pkmem_teardown() { + pk_funcinstr_teardown(); + pk_memory_teardown_all(); +} + /* static bool expected_exit = false; static bool caught = false; @@ -127,7 +143,7 @@ exit(int code) _exit(code); } } -// assert() calls abort(), handle +// pk_mem_assert() calls abort(), handle void handle_assert_abort(int sig) { @@ -149,14 +165,18 @@ int main(int argc, char *argv[]) int i; // pk_new<T> + pk_test_pkmem_spinup(true); + fprintf(stdout, "[pkmem.cpp] start: %s\n", test_basic_alloc); { char *some_dang_string = pk_new<char>(64); fprintf(stdout, "some_dang_string: %s: %p\n", some_dang_string, (void *)some_dang_string); pk_delete<char>(some_dang_string, 64); } - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); + fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_basic_alloc); // assert misalignment + pk_test_pkmem_spinup(true); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_misalignment01); { pk_membucket *bkt = pk_bucket_create("misalignment", 1024 * 1024, false); @@ -165,21 +185,22 @@ int main(int argc, char *argv[]) pk_new(9, 1, bkt); fprintf(stdout, "lastEmptyBlockIndex: %li\n", bkt->lastEmptyBlockIndex); - assert(1 == bkt->lastEmptyBlockIndex); + pk_mem_assert(1 == bkt->lastEmptyBlockIndex); fprintf(stdout, "head : %li\n", bkt->head); - assert(65 == bkt->head); + pk_mem_assert(65 == bkt->head); fprintf(stdout, "blocks[0].data : %p\n", (void *)bkt->blocks[0].data); - assert(bkt->ptr + 10 == bkt->blocks[0].data); + pk_mem_assert(bkt->ptr + 10 == bkt->blocks[0].data); fprintf(stdout, "blocks[0].size : %li\n", bkt->blocks[0].size); - assert(54 == bkt->blocks[0].size); + pk_mem_assert(54 == bkt->blocks[0].size); } fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_misalignment01); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); // assert misalignment + blank block test + pk_test_pkmem_spinup(); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_misalignment02); { pk_membucket *bkt = pk_bucket_create("misalignment", 1024 * 1024, false); @@ -188,51 +209,53 @@ int main(int argc, char *argv[]) pk_new(9, 16, bkt); fprintf(stdout, "lastEmptyBlockIndex: %li\n", bkt->lastEmptyBlockIndex); - assert(2 == bkt->lastEmptyBlockIndex); + pk_mem_assert(2 == bkt->lastEmptyBlockIndex); fprintf(stdout, "head : %li\n", bkt->head); - assert(65 == bkt->head); + pk_mem_assert(65 == bkt->head); fprintf(stdout, "blocks[0].data : %p\n", (void *)bkt->blocks[0].data); - assert(bkt->ptr + 1 == bkt->blocks[0].data); + pk_mem_assert(bkt->ptr + 1 == bkt->blocks[0].data); fprintf(stdout, "blocks[0].size : %li\n", bkt->blocks[0].size); - assert(15 == bkt->blocks[0].size); + pk_mem_assert(15 == bkt->blocks[0].size); fprintf(stdout, "blocks[1].data : %p\n", (void *)bkt->blocks[1].data); - assert(bkt->ptr + 25 == bkt->blocks[1].data); + pk_mem_assert(bkt->ptr + 25 == bkt->blocks[1].data); fprintf(stdout, "blocks[1].size : %li\n", bkt->blocks[1].size); - assert(39 == bkt->blocks[1].size); + pk_mem_assert(39 == bkt->blocks[1].size); } fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_misalignment02); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); // predictable free 0000 + pk_test_pkmem_spinup(true); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_free_0000); { FreeTest01 ft{}; ft.ensureState(); fprintf(stdout, "blocks[0].data : %p\n", (void *)ft.bkt->blocks[0].data); - assert(ft.bkt->ptr + 2 == ft.bkt->blocks[0].data); + pk_mem_assert(ft.bkt->ptr + 2 == ft.bkt->blocks[0].data); fprintf(stdout, "blocks[0].size : %li\n", ft.bkt->blocks[0].size); - assert(6 == ft.bkt->blocks[0].size); + pk_mem_assert(6 == ft.bkt->blocks[0].size); fprintf(stdout, "blocks[1].data : %p\n", (void *)ft.bkt->blocks[1].data); - assert(ft.bkt->ptr + 12 == ft.bkt->blocks[1].data); + pk_mem_assert(ft.bkt->ptr + 12 == ft.bkt->blocks[1].data); fprintf(stdout, "blocks[1].size : %li\n", ft.bkt->blocks[1].size); - assert(4 == ft.bkt->blocks[1].size); + pk_mem_assert(4 == ft.bkt->blocks[1].size); fprintf(stdout, "blocks[2].data : %p\n", (void *)ft.bkt->blocks[2].data); - assert(ft.bkt->ptr + 32 == ft.bkt->blocks[2].data); + pk_mem_assert(ft.bkt->ptr + 32 == ft.bkt->blocks[2].data); fprintf(stdout, "blocks[2].size : %li\n", ft.bkt->blocks[2].size); - assert(32 == ft.bkt->blocks[2].size); + pk_mem_assert(32 == ft.bkt->blocks[2].size); } fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_0000); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); // predictable free 1000 + pk_test_pkmem_spinup(); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_free_1000); { size_t expected_head = 80; @@ -246,29 +269,30 @@ int main(int argc, char *argv[]) pk_delete(ft.ptrs[free_index], ft.sz[free_index], ft.bkt); fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex); - assert(3 == ft.bkt->lastEmptyBlockIndex); + pk_mem_assert(3 == ft.bkt->lastEmptyBlockIndex); fprintf(stdout, "head : %li\n", ft.bkt->head); - assert(expected_head == ft.bkt->head); + pk_mem_assert(expected_head == ft.bkt->head); fprintf(stdout, "blocks[0].data : %p\n", (void *)ft.bkt->blocks[0].data); - assert(ft.bkt->ptr + 0 == ft.bkt->blocks[0].data); + pk_mem_assert(ft.bkt->ptr + 0 == ft.bkt->blocks[0].data); fprintf(stdout, "blocks[0].size : %li\n", ft.bkt->blocks[0].size); - assert(8 == ft.bkt->blocks[0].size); + pk_mem_assert(8 == ft.bkt->blocks[0].size); fprintf(stdout, "blocks[1].data : %p\n", (void *)ft.bkt->blocks[1].data); - assert(ft.bkt->ptr + 12 == ft.bkt->blocks[1].data); + pk_mem_assert(ft.bkt->ptr + 12 == ft.bkt->blocks[1].data); fprintf(stdout, "blocks[1].size : %li\n", ft.bkt->blocks[1].size); - assert(4 == ft.bkt->blocks[1].size); + pk_mem_assert(4 == ft.bkt->blocks[1].size); fprintf(stdout, "blocks[2].data : %p\n", (void *)ft.bkt->blocks[2].data); - assert(ft.bkt->ptr + 32 == ft.bkt->blocks[2].data); + pk_mem_assert(ft.bkt->ptr + 32 == ft.bkt->blocks[2].data); fprintf(stdout, "blocks[2].size : %li\n", ft.bkt->blocks[2].size); - assert(32 == ft.bkt->blocks[2].size); + pk_mem_assert(32 == ft.bkt->blocks[2].size); } fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_1000); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); // predictable free 0100 + pk_test_pkmem_spinup(); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_free_0100); { size_t expected_head = 32; @@ -282,24 +306,25 @@ int main(int argc, char *argv[]) pk_delete(ft.ptrs[free_index], ft.sz[free_index], ft.bkt); fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex); - assert(2 == ft.bkt->lastEmptyBlockIndex); + pk_mem_assert(2 == ft.bkt->lastEmptyBlockIndex); fprintf(stdout, "head : %li\n", ft.bkt->head); - assert(expected_head == ft.bkt->head); + pk_mem_assert(expected_head == ft.bkt->head); fprintf(stdout, "blocks[0].data : %p\n", (void *)ft.bkt->blocks[0].data); - assert(ft.bkt->ptr + 2 == ft.bkt->blocks[0].data); + pk_mem_assert(ft.bkt->ptr + 2 == ft.bkt->blocks[0].data); fprintf(stdout, "blocks[0].size : %li\n", ft.bkt->blocks[0].size); - assert(6 == ft.bkt->blocks[0].size); + pk_mem_assert(6 == ft.bkt->blocks[0].size); fprintf(stdout, "blocks[1].data : %p\n", (void *)ft.bkt->blocks[1].data); - assert(ft.bkt->ptr + 12 == ft.bkt->blocks[1].data); + pk_mem_assert(ft.bkt->ptr + 12 == ft.bkt->blocks[1].data); fprintf(stdout, "blocks[1].size : %li\n", ft.bkt->blocks[1].size); - assert(4 == ft.bkt->blocks[1].size); + pk_mem_assert(4 == ft.bkt->blocks[1].size); } fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_0100); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); // predictable free 0010 + pk_test_pkmem_spinup(); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_free_0010); { size_t expected_head = 80; @@ -314,24 +339,25 @@ int main(int argc, char *argv[]) pk_delete(ft.ptrs[free_index], ft.sz[free_index], ft.bkt); fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex); - assert(2 == ft.bkt->lastEmptyBlockIndex); + pk_mem_assert(2 == ft.bkt->lastEmptyBlockIndex); fprintf(stdout, "head : %li\n", ft.bkt->head); - assert(expected_head == ft.bkt->head); + pk_mem_assert(expected_head == ft.bkt->head); fprintf(stdout, "blocks[0].data : %p\n", (void *)ft.bkt->blocks[0].data); - assert(ft.bkt->ptr + 2 == ft.bkt->blocks[0].data); + pk_mem_assert(ft.bkt->ptr + 2 == ft.bkt->blocks[0].data); fprintf(stdout, "blocks[0].size : %li\n", ft.bkt->blocks[0].size); - assert(6 == ft.bkt->blocks[0].size); + pk_mem_assert(6 == ft.bkt->blocks[0].size); fprintf(stdout, "blocks[1].data : %p\n", (void *)ft.bkt->blocks[1].data); - assert(ft.bkt->ptr + 12 == ft.bkt->blocks[1].data); + pk_mem_assert(ft.bkt->ptr + 12 == ft.bkt->blocks[1].data); fprintf(stdout, "blocks[1].size : %li\n", ft.bkt->blocks[1].size); - assert(52 == ft.bkt->blocks[1].size); + pk_mem_assert(52 == ft.bkt->blocks[1].size); } fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_0010); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); // predictable free 0001 + pk_test_pkmem_spinup(); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_free_0001); { size_t expected_head = 80; @@ -346,24 +372,25 @@ int main(int argc, char *argv[]) pk_delete(ft.ptrs[free_index], ft.sz[free_index], ft.bkt); fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex); - assert(2 == ft.bkt->lastEmptyBlockIndex); + pk_mem_assert(2 == ft.bkt->lastEmptyBlockIndex); fprintf(stdout, "head : %li\n", ft.bkt->head); - assert(expected_head == ft.bkt->head); + pk_mem_assert(expected_head == ft.bkt->head); fprintf(stdout, "blocks[0].data : %p\n", (void *)ft.bkt->blocks[0].data); - assert(ft.bkt->ptr + 2 == ft.bkt->blocks[0].data); + pk_mem_assert(ft.bkt->ptr + 2 == ft.bkt->blocks[0].data); fprintf(stdout, "blocks[0].size : %li\n", ft.bkt->blocks[0].size); - assert(14 == ft.bkt->blocks[0].size); + pk_mem_assert(14 == ft.bkt->blocks[0].size); fprintf(stdout, "blocks[1].data : %p\n", (void *)ft.bkt->blocks[1].data); - assert(ft.bkt->ptr + 32 == ft.bkt->blocks[1].data); + pk_mem_assert(ft.bkt->ptr + 32 == ft.bkt->blocks[1].data); fprintf(stdout, "blocks[1].size : %li\n", ft.bkt->blocks[1].size); - assert(32 == ft.bkt->blocks[1].size); + pk_mem_assert(32 == ft.bkt->blocks[1].size); } fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_0001); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); // ensure free touching after only + pk_test_pkmem_spinup(); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_free_after); { FreeTest02 ft{}; @@ -374,24 +401,25 @@ int main(int argc, char *argv[]) pk_delete(ft.ptrs[0], ft.sz[0], ft.bkt); fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex); - assert(2 == ft.bkt->lastEmptyBlockIndex); + pk_mem_assert(2 == ft.bkt->lastEmptyBlockIndex); fprintf(stdout, "head : %li\n", ft.bkt->head); - assert(65 == ft.bkt->head); + pk_mem_assert(65 == ft.bkt->head); fprintf(stdout, "blocks[0].data : %p\n", (void *)ft.bkt->blocks[0].data); - assert(ft.bkt->ptr + 0 == ft.bkt->blocks[0].data); + pk_mem_assert(ft.bkt->ptr + 0 == ft.bkt->blocks[0].data); fprintf(stdout, "blocks[0].size : %li\n", ft.bkt->blocks[0].size); - assert(32 == ft.bkt->blocks[0].size); + pk_mem_assert(32 == ft.bkt->blocks[0].size); fprintf(stdout, "blocks[1].data : %p\n", (void *)ft.bkt->blocks[1].data); - assert(ft.bkt->ptr + 33 == ft.bkt->blocks[1].data); + pk_mem_assert(ft.bkt->ptr + 33 == ft.bkt->blocks[1].data); fprintf(stdout, "blocks[1].size : %li\n", ft.bkt->blocks[1].size); - assert(31 == ft.bkt->blocks[1].size); + pk_mem_assert(31 == ft.bkt->blocks[1].size); } fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_after); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); // ensure free touching before only + pk_test_pkmem_spinup(); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_free_before); { FreeTest02 ft{}; @@ -411,22 +439,22 @@ int main(int argc, char *argv[]) void *ptr5 = pk_new( 1, 1, ft.bkt); fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex); - assert(0 == ft.bkt->lastEmptyBlockIndex); + pk_mem_assert(0 == ft.bkt->lastEmptyBlockIndex); fprintf(stdout, "head : %li\n", ft.bkt->head); - assert(66 == ft.bkt->head); + pk_mem_assert(66 == ft.bkt->head); fprintf(stdout, "ptr0 : %p\n", ft.ptrs[0]); - assert(ft.bkt->ptr + 0 == ft.ptrs[0]); + pk_mem_assert(ft.bkt->ptr + 0 == ft.ptrs[0]); fprintf(stdout, "ptr3 : %p\n", ptr3); - assert(ft.bkt->ptr + 19 == ptr3); + pk_mem_assert(ft.bkt->ptr + 19 == ptr3); fprintf(stdout, "ptr2 : %p\n", ft.ptrs[2]); - assert(ft.bkt->ptr + 32 == ft.ptrs[2]); + pk_mem_assert(ft.bkt->ptr + 32 == ft.ptrs[2]); fprintf(stdout, "ptr4 : %p\n", ptr4); - assert(ft.bkt->ptr + 33 == ptr4); + pk_mem_assert(ft.bkt->ptr + 33 == ptr4); fprintf(stdout, "ptr1 : %p\n", ft.ptrs[1]); - assert(ft.bkt->ptr + 64 == ft.ptrs[1]); + pk_mem_assert(ft.bkt->ptr + 64 == ft.ptrs[1]); fprintf(stdout, "ptr5 : %p\n", ptr5); - assert(ft.bkt->ptr + 65 == ptr5); + pk_mem_assert(ft.bkt->ptr + 65 == ptr5); /* free [19-31] [00-18] (19) ptr0 @@ -441,27 +469,27 @@ int main(int argc, char *argv[]) ptr3 = nullptr; fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex); - assert(1 == ft.bkt->lastEmptyBlockIndex); + pk_mem_assert(1 == ft.bkt->lastEmptyBlockIndex); fprintf(stdout, "head : %li\n", ft.bkt->head); - assert(66 == ft.bkt->head); + pk_mem_assert(66 == ft.bkt->head); fprintf(stdout, "ptr0 : %p\n", ft.ptrs[0]); - assert(ft.bkt->ptr + 0 == ft.ptrs[0]); + pk_mem_assert(ft.bkt->ptr + 0 == ft.ptrs[0]); fprintf(stdout, "ptr3 : %p\n", ptr3); - assert(nullptr == ptr3); + pk_mem_assert(nullptr == ptr3); fprintf(stdout, "ptr2 : %p\n", ft.ptrs[2]); - assert(ft.bkt->ptr + 32 == ft.ptrs[2]); + pk_mem_assert(ft.bkt->ptr + 32 == ft.ptrs[2]); fprintf(stdout, "ptr4 : %p\n", ptr4); - assert(ft.bkt->ptr + 33 == ptr4); + pk_mem_assert(ft.bkt->ptr + 33 == ptr4); fprintf(stdout, "ptr1 : %p\n", ft.ptrs[1]); - assert(ft.bkt->ptr + 64 == ft.ptrs[1]); + pk_mem_assert(ft.bkt->ptr + 64 == ft.ptrs[1]); fprintf(stdout, "ptr5 : %p\n", ptr5); - assert(ft.bkt->ptr + 65 == ptr5); + pk_mem_assert(ft.bkt->ptr + 65 == ptr5); fprintf(stdout, "blocks[0].data : %p\n", (void *)ft.bkt->blocks[0].data); - assert(ft.bkt->ptr + 19 == ft.bkt->blocks[0].data); + pk_mem_assert(ft.bkt->ptr + 19 == ft.bkt->blocks[0].data); fprintf(stdout, "blocks[0].size : %li\n", ft.bkt->blocks[0].size); - assert(13 == ft.bkt->blocks[0].size); + pk_mem_assert(13 == ft.bkt->blocks[0].size); /* free [32] which gets absorbed into 19-32 [19-32] (13) memblock @@ -471,32 +499,33 @@ int main(int argc, char *argv[]) ft.ptrs[2] = nullptr; fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex); - assert(1 == ft.bkt->lastEmptyBlockIndex); + pk_mem_assert(1 == ft.bkt->lastEmptyBlockIndex); fprintf(stdout, "head : %li\n", ft.bkt->head); - assert(66 == ft.bkt->head); + pk_mem_assert(66 == ft.bkt->head); fprintf(stdout, "ptr0 : %p\n", ft.ptrs[0]); - assert(ft.bkt->ptr + 0 == ft.ptrs[0]); + pk_mem_assert(ft.bkt->ptr + 0 == ft.ptrs[0]); fprintf(stdout, "ptr3 : %p\n", ptr3); - assert(nullptr == ptr3); + pk_mem_assert(nullptr == ptr3); fprintf(stdout, "ptr2 : %p\n", ft.ptrs[2]); - assert(nullptr == ft.ptrs[2]); + pk_mem_assert(nullptr == ft.ptrs[2]); fprintf(stdout, "ptr4 : %p\n", ptr4); - assert(ft.bkt->ptr + 33 == ptr4); + pk_mem_assert(ft.bkt->ptr + 33 == ptr4); fprintf(stdout, "ptr1 : %p\n", ft.ptrs[1]); - assert(ft.bkt->ptr + 64 == ft.ptrs[1]); + pk_mem_assert(ft.bkt->ptr + 64 == ft.ptrs[1]); fprintf(stdout, "ptr5 : %p\n", ptr5); - assert(ft.bkt->ptr + 65 == ptr5); + pk_mem_assert(ft.bkt->ptr + 65 == ptr5); fprintf(stdout, "blocks[0].data : %p\n", (void *)ft.bkt->blocks[0].data); - assert(ft.bkt->ptr + 19 == ft.bkt->blocks[0].data); + pk_mem_assert(ft.bkt->ptr + 19 == ft.bkt->blocks[0].data); fprintf(stdout, "blocks[0].size : %li\n", ft.bkt->blocks[0].size); - assert(14 == ft.bkt->blocks[0].size); + pk_mem_assert(14 == ft.bkt->blocks[0].size); } fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_before); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); // ensure free touching before and after + pk_test_pkmem_spinup(); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_free_between); { FreeTest02 ft{}; @@ -508,25 +537,26 @@ int main(int argc, char *argv[]) ft.ptrs[2] = nullptr; fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex); - assert(1 == ft.bkt->lastEmptyBlockIndex); + pk_mem_assert(1 == ft.bkt->lastEmptyBlockIndex); fprintf(stdout, "head : %li\n", ft.bkt->head); - assert(65 == ft.bkt->head); + pk_mem_assert(65 == ft.bkt->head); fprintf(stdout, "ptr0 : %p\n", ft.ptrs[0]); - assert(ft.bkt->ptr + 0 == ft.ptrs[0]); + pk_mem_assert(ft.bkt->ptr + 0 == ft.ptrs[0]); fprintf(stdout, "ptr2 : %p\n", ft.ptrs[2]); - assert(nullptr == ft.ptrs[2]); + pk_mem_assert(nullptr == ft.ptrs[2]); fprintf(stdout, "ptr1 : %p\n", ft.ptrs[1]); - assert(ft.bkt->ptr + 64 == ft.ptrs[1]); + pk_mem_assert(ft.bkt->ptr + 64 == ft.ptrs[1]); fprintf(stdout, "blocks[0].data : %p\n", (void *)ft.bkt->blocks[0].data); - assert(ft.bkt->ptr + 19 == ft.bkt->blocks[0].data); + pk_mem_assert(ft.bkt->ptr + 19 == ft.bkt->blocks[0].data); fprintf(stdout, "blocks[0].size : %li\n", ft.bkt->blocks[0].size); - assert(45 == ft.bkt->blocks[0].size); + pk_mem_assert(45 == ft.bkt->blocks[0].size); } fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_between); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); + pk_test_pkmem_spinup(); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_alloc_strings); { size_t diff; @@ -545,62 +575,65 @@ int main(int argc, char *argv[]) diff = str1 - bkt->ptr; fprintf(stdout, "str1 - ptr : %zu\n", diff); - assert(diff == 0); + pk_mem_assert(diff == 0); diff = str2 - str1; fprintf(stdout, "str2 - str1 : %zu\n", diff); - assert(diff == 16); + pk_mem_assert(diff == 16); diff = str2 - bkt->ptr; fprintf(stdout, "str2 - ptr : %zu\n", diff); - assert(diff == 16); + pk_mem_assert(diff == 16); diff = (char *)handle1 - str1; fprintf(stdout, "handle1 - str1 : %zu\n", diff); - assert(diff == 32); + pk_mem_assert(diff == 32); diff = (char *)handle2 - (char *)handle1; fprintf(stdout, "handle2 - handle1 : %zu\n", diff); - assert(diff == 8); + pk_mem_assert(diff == 8); pk_bucket_destroy(bkt); } fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_alloc_strings); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); // assert bucket count + pk_test_pkmem_spinup(false); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_bucket_count01); do { for (i = 0; i < PK_MAX_BUCKET_COUNT; ++i) { pk_membucket *bkt = pk_bucket_create("lol", 1024, false); - assert(bkt != nullptr); + pk_mem_assert(bkt != nullptr); (void)bkt; } pk_membucket *bkt = pk_bucket_create("lol", 1024, false); - assert(bkt == nullptr); + pk_mem_assert(bkt == nullptr); } while(false); fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_bucket_count01); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); // assert no buckets available on pk_new with full memory + pk_test_pkmem_spinup(false); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_bucket_count02); do { for (i = 0; i < PK_MAX_BUCKET_COUNT; ++i) { pk_membucket *bkt = pk_bucket_create("lol2", 1024, false); char *asdf = pk_new<char>(768, bkt); - assert(asdf != nullptr); + pk_mem_assert(asdf != nullptr); } char *asdf = pk_new<char>(768); - assert(asdf == nullptr); + pk_mem_assert(asdf == nullptr); } while(false); fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_bucket_count02); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); // assert no buckets available on pk_new with full memory + pk_test_pkmem_spinup(false); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_bucket_count03); do { @@ -608,15 +641,16 @@ int main(int argc, char *argv[]) for (i = 0; i < PK_MAX_BUCKET_COUNT; ++i) { bkt = pk_bucket_create("lol3", 1024, false); char *asdf = pk_new<char>(768, bkt); - assert(asdf != nullptr); + pk_mem_assert(asdf != nullptr); } char *asdf = pk_new<char>(768, bkt); - assert(asdf == nullptr); + pk_mem_assert(asdf == nullptr); } while(false); fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_bucket_count03); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); + pk_test_pkmem_spinup(false); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_bucket_count04); { pk_membucket *bkt1 = pk_bucket_create("bucket1", 1024, false); @@ -625,36 +659,37 @@ int main(int argc, char *argv[]) pk_membucket *bkt4 = pk_bucket_create("bucket4", 1024, false); fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head); - assert(4 == pk_bucket_head); + pk_mem_assert(4 == pk_bucket_head); pk_bucket_destroy(bkt4); fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head); - assert(3 == pk_bucket_head); + pk_mem_assert(3 == pk_bucket_head); pk_bucket_destroy(bkt3); fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head); - assert(2 == pk_bucket_head); + pk_mem_assert(2 == pk_bucket_head); pk_bucket_destroy(bkt2); fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head); - assert(1 == pk_bucket_head); + pk_mem_assert(1 == pk_bucket_head); pk_bucket_destroy(bkt1); fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head); - assert(0 == pk_bucket_head); + pk_mem_assert(0 == pk_bucket_head); } fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_bucket_count04); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); /* 2025-01-06 JCB * buckets are stored in an array. * pk_bucket_head is only an *indicator* of how many buckets have been * created total, and the index of the next available. */ + pk_test_pkmem_spinup(false); fprintf(stdout, "[pkmem.cpp] start: %s\n", test_bucket_count05); { pk_membucket *bkt1 = pk_bucket_create("bucket1", 1024, false); @@ -663,30 +698,30 @@ int main(int argc, char *argv[]) pk_membucket *bkt4 = pk_bucket_create("bucket4", 1024, false); fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head); - assert(4 == pk_bucket_head); + pk_mem_assert(4 == pk_bucket_head); pk_bucket_destroy(bkt1); fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head); - assert(4 == pk_bucket_head); + pk_mem_assert(4 == pk_bucket_head); pk_bucket_destroy(bkt2); fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head); - assert(4 == pk_bucket_head); + pk_mem_assert(4 == pk_bucket_head); pk_bucket_destroy(bkt3); fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head); - assert(4 == pk_bucket_head); + pk_mem_assert(4 == pk_bucket_head); pk_bucket_destroy(bkt4); fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head); - assert(3 == pk_bucket_head); + pk_mem_assert(3 == pk_bucket_head); pk_memory_flush(); fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head); - assert(0 == pk_bucket_head); + pk_mem_assert(0 == pk_bucket_head); } fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_bucket_count05); - pk_memory_teardown_all(); + pk_test_pkmem_teardown(); return 0; } diff --git a/test/pkuuid.c b/test/pkuuid.c index 8b489aa..d4f47ed 100644 --- a/test/pkuuid.c +++ b/test/pkuuid.c @@ -9,6 +9,9 @@ #include "../pktmr.h" +#define PK_IMPL_FUNCINSTR +#include "../pkfuncinstr.h" + #include <stdio.h> void @@ -92,6 +95,7 @@ main(int argc, char *argv[]) if (equals != false) exit(1); } + pk_funcinstr_init(); { const int count = 4; struct pk_uuid ids[count]; @@ -110,8 +114,10 @@ main(int argc, char *argv[]) } fprintf(stdout, "\n"); } + pk_funcinstr_teardown(); // test parse + pk_funcinstr_init(); { bool res; unsigned char i; @@ -146,6 +152,7 @@ main(int argc, char *argv[]) } fprintf(stdout, "\n"); } + pk_funcinstr_teardown(); { double ms; |
