diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-06-02 11:29:00 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-06-02 12:13:43 -0400 |
| commit | d6630a778a69cd5086bac5d62f39e7d38d2370a0 (patch) | |
| tree | f8bceac3c3342a87665cfa96fd4e0b4619825117 | |
| parent | e5d72d819e82e21270a0543ad24eb740fb693a19 (diff) | |
pkmem: cleanup, speed, debugger track head l&r
| -rw-r--r-- | pkmem.h | 143 |
1 files changed, 95 insertions, 48 deletions
@@ -35,6 +35,7 @@ void pk_delete(const void* ptr, size_t sz, struct pk_membucket* bkt); #if defined(__cplusplus) #include <type_traits> +#include <new> static inline void stupid_header_warnings_cpp() { (void)std::is_const<void>::value; } @@ -169,7 +170,8 @@ struct pk_dbg_memblock { struct pk_membucket *bkt; }; static struct pk_dbg_memblock debug_all_allocs[1024 * 1024]; -static atomic_size_t debug_alloc_head = 0; +static atomic_size_t debug_alloc_head_l = 0; +static atomic_size_t debug_alloc_head_r = 0; static atomic_bool has_init_debug = false; static mtx_t debug_alloc_mtx; #endif @@ -184,10 +186,12 @@ pk_memory_is_in_bucket(const void* ptr, const struct pk_membucket* bkt) void pk_memory_debug_print() { - size_t i, d; + size_t i; #ifdef PK_MEMORY_DEBUGGER + size_t d; size_t count = 0; - size_t dah = debug_alloc_head; + size_t dahl = debug_alloc_head_l; + size_t dahr = debug_alloc_head_r; #endif PK_LOGV_INF("Memory Manager printout:\nBucket count: %li\n", pk_bucket_head); for (i = 0; i < pk_bucket_head; ++i) { @@ -203,13 +207,14 @@ pk_memory_debug_print() PK_LOGV_INF("\tptr: %p\n", (void *)pk_buckets[i].ptr); PK_LOGV_INF("\ttransient: %i\n", pk_buckets[i].transient); #ifdef PK_MEMORY_DEBUGGER - for (d = 0; d < dah; ++d) { + for (d = 0; d < dahr; ++d) { if (debug_all_allocs[d].bkt == &pk_buckets[d] && debug_all_allocs[d].blk.size > 0) { count += 1; } } PK_LOGV_INF("\tdebug alloc count: %lu\n", count); - PK_LOGV_INF("\tdebug alloc last: %lu\n", dah); + PK_LOGV_INF("\tdebug alloc head_l: %lu\n", dahl); + PK_LOGV_INF("\tdebug alloc head_r: %lu\n", dahr); #endif } } @@ -236,7 +241,8 @@ pk_memory_teardown_all() } pk_bucket_head = 0; #ifdef PK_MEMORY_DEBUGGER - debug_alloc_head = 0; + debug_alloc_head_l = 0; + debug_alloc_head_r = 0; mtx_destroy(&debug_alloc_mtx); has_init_debug = false; #endif @@ -250,7 +256,6 @@ pk_bucket_create_inner(int64_t sz, bool transient, const char* description) if (has_init_debug == false) { has_init_debug = true; mtx_init(&debug_alloc_mtx, mtx_plain); - memset(debug_all_allocs, 0, sizeof(struct pk_dbg_memblock) * 1024 * 1024); } #endif int64_t blockCount = sz * 0.01; @@ -264,9 +269,6 @@ pk_bucket_create_inner(int64_t sz, bool transient, const char* description) bkt->blocks = (struct pk_memblock*)malloc(sz); mtx_init(&bkt->mtx, mtx_plain); assert(bkt->blocks != nullptr && "failed to allocate memory"); -#if 1 - memset(bkt->blocks, 0, sz); -#endif bkt->ptr = ((char*)(bkt->blocks)) + (sizeof(struct pk_memblock) * bkt->maxBlockCount); size_t misalignment = (size_t)(bkt->ptr) % PK_MAXIMUM_ALIGNMENT; if (misalignment != 0) { @@ -295,9 +297,6 @@ void pk_bucket_destroy(struct pk_membucket* bkt) { size_t i; -#ifdef PK_MEMORY_DEBUGGER - size_t dah; -#endif for (i = 0; i < pk_bucket_head; ++i) { if (&pk_buckets[i] == bkt) { if (pk_bucket_head == i + 1) @@ -305,7 +304,7 @@ pk_bucket_destroy(struct pk_membucket* bkt) break; } } - free(bkt->blocks); + if (bkt->blocks != NULL && bkt->blocks != CAFE_BABE(struct pk_memblock)) free(bkt->blocks); bkt->size = 0; bkt->head = 0; bkt->lostBytes = 0; @@ -317,13 +316,28 @@ pk_bucket_destroy(struct pk_membucket* bkt) bkt->transient = false; mtx_destroy(&bkt->mtx); #ifdef PK_MEMORY_DEBUGGER - dah = debug_alloc_head; - for (i = dah; i > 0; --i) { - if (debug_all_allocs[i].bkt == bkt) { - debug_all_allocs[i].blk.data = NULL; - debug_all_allocs[i].blk.size = 0u; + mtx_lock(&debug_alloc_mtx); + size_t dahl = debug_alloc_head_l; + size_t dahr = debug_alloc_head_r; + size_t found_dahl = dahl; + for (i = dahr; i > 0; --i) { + if (debug_all_allocs[i-1].bkt == bkt) { + if (i < found_dahl) { + if (found_dahl == dahr) { + dahr = i; + } + found_dahl = i; + } + debug_all_allocs[i-1].blk.data = NULL; + debug_all_allocs[i-1].blk.size = 0u; } } + debug_alloc_head_l = found_dahl; + debug_alloc_head_r = dahr; +#ifdef PK_MEMORY_DEBUGGER_L2 + assert(debug_alloc_head_l <= debug_alloc_head_r); +#endif + mtx_unlock(&debug_alloc_mtx); #endif } @@ -343,12 +357,28 @@ pk_bucket_reset(struct pk_membucket* bkt) bkt->blocks->data = bkt->ptr; bkt->blocks->size = bkt->size - (sizeof(struct pk_memblock) * bkt->maxBlockCount); #ifdef PK_MEMORY_DEBUGGER - for (i = debug_alloc_head; i > 0; --i) { - if (debug_all_allocs[i].bkt == bkt) { - debug_all_allocs[i].blk.data = NULL; - debug_all_allocs[i].blk.size = 0u; + mtx_lock(&debug_alloc_mtx); + size_t dahl = debug_alloc_head_l; + size_t dahr = debug_alloc_head_r; + size_t found_dahl = dahl; + for (i = dahr; i > 0; --i) { + if (debug_all_allocs[i-1].bkt == bkt) { + if (i < found_dahl) { + if (found_dahl == dahr) { + dahr = i; + } + found_dahl = i; + } + debug_all_allocs[i-1].blk.data = NULL; + debug_all_allocs[i-1].blk.size = 0u; } } + debug_alloc_head_l = found_dahl; + debug_alloc_head_r = dahr; +#ifdef PK_MEMORY_DEBUGGER_L2 + assert(debug_alloc_head_l <= debug_alloc_head_r); +#endif + mtx_unlock(&debug_alloc_mtx); #endif } @@ -434,25 +464,29 @@ pk_new_bkt(size_t sz, size_t alignment, struct pk_membucket* bkt) } data = block->data + misalignment; #ifdef PK_MEMORY_DEBUGGER - bool handled = bkt->transient; - struct pk_dbg_memblock* mb = nullptr; - if (handled == false) { - for (i = 0; i < debug_alloc_head; ++i) { - mb = &debug_all_allocs[i]; - if (mb->bkt != NULL) continue; - assert((mb->blk.size == 0 || (void*)(mb->blk.data) != data) && "mem address alloc'd twice!"); - if (mb->blk.size == 0) { - mb->blk.data = (char*)(data); - mb->blk.size = sz; - mb->bkt = bkt; - handled = true; - break; - } + size_t dahr = debug_alloc_head_r; + size_t ii; + if (bkt->transient == false) { + for (i = 0; i < dahr; ++i) { + if (debug_all_allocs[i].bkt != NULL) continue; + assert((debug_all_allocs[i].blk.size == 0 || (void*)(debug_all_allocs[i].blk.data) != data) && "mem address alloc'd twice!"); } - } - if (handled == false) { mtx_lock(&debug_alloc_mtx); - i = debug_alloc_head++; + i = debug_alloc_head_l; + if (debug_alloc_head_l == debug_alloc_head_r) { + debug_alloc_head_l++; + debug_alloc_head_r++; + } else { + for (ii = debug_alloc_head_l+1; ii <= dahr; ++ii) { + if (debug_all_allocs[ii].bkt == NULL) { + debug_alloc_head_l = ii; + break; + } + } + } +#ifdef PK_MEMORY_DEBUGGER_L2 + assert(debug_alloc_head_l <= debug_alloc_head_r); +#endif mtx_unlock(&debug_alloc_mtx); debug_all_allocs[i].blk.data = (char*)data; debug_all_allocs[i].blk.size = sz; @@ -491,7 +525,8 @@ pk_new_bkt(size_t sz, size_t alignment, struct pk_membucket* bkt) if (!bkt->transient) { int64_t debug_tracked_alloc_size = 0; int64_t debug_bucket_alloc_size = bkt->size - (sizeof(struct pk_memblock) * bkt->maxBlockCount); - for (i = 0; i < debug_alloc_head; ++i) { + size_t dahr = debug_alloc_head_r; + for (i = 0; i < dahr; ++i) { if (debug_all_allocs[i].bkt != bkt) continue; debug_tracked_alloc_size += debug_all_allocs[i].blk.size; } @@ -502,6 +537,7 @@ pk_new_bkt(size_t sz, size_t alignment, struct pk_membucket* bkt) } #endif mtx_unlock(&bkt->mtx); + memset(data, 0, sz); return data; } @@ -538,7 +574,11 @@ void pk_delete_bkt(const void* ptr, size_t sz, struct pk_membucket* bkt) { #ifdef PK_MEMORY_FORCE_MALLOC +#if defined(__cplusplus) return std::free(const_cast<void*>(ptr)); +#else + return free((void*)ptr); +#endif #endif size_t i; mtx_lock(&bkt->mtx); @@ -546,13 +586,13 @@ pk_delete_bkt(const void* ptr, size_t sz, struct pk_membucket* bkt) assert(ptr >= bkt->raw && (char*)ptr < bkt->ptr + bkt->size && "pointer not in memory bucket range"); assert(sz > 0 && "attempted to free pointer of size 0"); #ifdef PK_MEMORY_DEBUGGER - size_t ii; bool found = bkt->transient; + struct pk_dbg_memblock* mb; mtx_lock(&debug_alloc_mtx); if (found == false) { - for (ii = debug_alloc_head; ii > 0; --ii) { - i = ii-1; - struct pk_dbg_memblock* mb = &debug_all_allocs[i]; + size_t dahr = debug_alloc_head_r; + for (i = dahr; i > 0; --i) { + mb = &debug_all_allocs[i-1]; if (mb->bkt != bkt) continue; if (mb->blk.size == 0) continue; if ((void*)(mb->blk.data) == ptr) { @@ -560,9 +600,15 @@ pk_delete_bkt(const void* ptr, size_t sz, struct pk_membucket* bkt) mb->blk.size = 0; mb->bkt = NULL; found = true; - if (i == (debug_alloc_head - 1)) { - debug_alloc_head--; + if (i <= debug_alloc_head_l) { + debug_alloc_head_l = i-1; + } + if (i == debug_alloc_head_r) { + debug_alloc_head_r--; } +#ifdef PK_MEMORY_DEBUGGER_L2 + assert(debug_alloc_head_l <= debug_alloc_head_r); +#endif break; } } @@ -623,7 +669,8 @@ pk_delete_bkt(const void* ptr, size_t sz, struct pk_membucket* bkt) if (!bkt->transient) { int64_t debug_tracked_alloc_size = 0; int64_t debug_bucket_alloc_size = bkt->size - (sizeof(struct pk_memblock) * bkt->maxBlockCount); - for (i = 0; i < debug_alloc_head; ++i) { + size_t dahr = debug_alloc_head_r; + for (i = 0; i < dahr; ++i) { if (debug_all_allocs[i].bkt != bkt) continue; debug_tracked_alloc_size += debug_all_allocs[i].blk.size; } |
