summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-06-02 11:29:00 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-06-02 12:13:43 -0400
commitd6630a778a69cd5086bac5d62f39e7d38d2370a0 (patch)
treef8bceac3c3342a87665cfa96fd4e0b4619825117
parente5d72d819e82e21270a0543ad24eb740fb693a19 (diff)
pkmem: cleanup, speed, debugger track head l&r
-rw-r--r--pkmem.h143
1 files changed, 95 insertions, 48 deletions
diff --git a/pkmem.h b/pkmem.h
index a83aea5..958875c 100644
--- a/pkmem.h
+++ b/pkmem.h
@@ -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;
}