summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-06-04 14:46:21 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-06-04 14:50:26 -0400
commit08d54867148420da3bd7ce531beaeb34de975fcb (patch)
tree0c0f0ef8f8629289472b7d86106d47aa4fea481d
parenta9a0920f431c76f31157edd42c6d055b673ed12f (diff)
pkmem.h: chkpt: major refactor for ad-hoc buckets
-rw-r--r--pkmem-types.h6
-rw-r--r--pkmem.h732
-rw-r--r--test/pkmem.c5
-rw-r--r--test/pkmem.cpp473
4 files changed, 604 insertions, 612 deletions
diff --git a/pkmem-types.h b/pkmem-types.h
index 7f7a2ac..2bf7752 100644
--- a/pkmem-types.h
+++ b/pkmem-types.h
@@ -54,6 +54,12 @@ pk_handle_validate_constexpr()
struct pk_membucket;
+enum PK_MEMBUCKET_FLAGS : uint64_t {
+ PK_MEMBUCKET_FLAG_NONE = (0),
+ PK_MEMBUCKET_FLAG_TRANSIENT = (1 << 01l),
+ PK_MEMBUCKET_FLAG_ALL = (0xFFFFFFFFFFFFFFFF),
+};
+
#endif /* PK_MEM_TYPES_H */
#ifdef PK_IMPL_MEM_TYPES
diff --git a/pkmem.h b/pkmem.h
index 958875c..adfaa36 100644
--- a/pkmem.h
+++ b/pkmem.h
@@ -16,12 +16,13 @@
# define PK_MAXIMUM_ALIGNMENT 64
#endif
-struct pk_membucket* pk_bucket_create(const char* description, int64_t sz, bool transient);
+size_t pk_mem_calculate_bkt_size(size_t sz, size_t reserved_block_count);
+struct pk_membucket* pk_bucket_create(const char* description, int64_t sz, enum PK_MEMBUCKET_FLAGS flags);
void pk_bucket_destroy(struct pk_membucket* bkt);
void pk_bucket_reset(struct pk_membucket* bkt);
+void pk_bucket_set_client_bucket(struct pk_membucket *bkt);
-void pk_memory_debug_print();
-void pk_memory_flush();
+void pk_memory_debug_print(struct pk_membucket *bkt);
void pk_memory_teardown_all();
bool pk_memory_is_in_bucket(const void* ptr, const struct pk_membucket* bkt);
@@ -41,9 +42,9 @@ static inline void stupid_header_warnings_cpp() { (void)std::is_const<void>::val
template <typename T>
inline T*
-pk_new(pk_membucket* bucket = nullptr)
+pk_new(pk_membucket* bucket = NULL)
{
- void* ptr = nullptr;
+ void* ptr = NULL;
if (bucket) {
ptr = pk_new_bkt(sizeof(T), alignof(T), bucket);
} else {
@@ -57,15 +58,15 @@ pk_new(pk_membucket* bucket = nullptr)
template <typename T>
inline T*
-pk_new(long count, pk_membucket* bucket = nullptr)
+pk_new(long count, pk_membucket* bucket = NULL)
{
- char* ptr = nullptr;
+ char* ptr = NULL;
if (bucket) {
ptr = static_cast<char*>(pk_new_bkt(sizeof(T) * count, alignof(T), bucket));
} else {
ptr = static_cast<char*>(pk_new_base(sizeof(T) * count, alignof(T)));
}
- if (ptr == nullptr) return nullptr;
+ if (ptr == NULL) return NULL;
if IS_CONSTRUCTIBLE(T) {
for (long i = 0; i < count; ++i) {
new (ptr + (i * sizeof(T))) T{};
@@ -76,7 +77,7 @@ pk_new(long count, pk_membucket* bucket = nullptr)
template <typename T>
inline void
-pk_delete(const T* ptr, pk_membucket* bucket = nullptr)
+pk_delete(const T* ptr, pk_membucket* bucket = NULL)
{
if IS_DESTRUCTIBLE(T) {
reinterpret_cast<const T*>(ptr)->~T();
@@ -90,7 +91,7 @@ pk_delete(const T* ptr, pk_membucket* bucket = nullptr)
template <typename T>
inline void
-pk_delete(const T* ptr, long count, pk_membucket* bucket = nullptr)
+pk_delete(const T* ptr, long count, pk_membucket* bucket = NULL)
{
if IS_DESTRUCTIBLE(T) {
for (long i = 0; i < count; ++i) {
@@ -118,311 +119,290 @@ pk_delete(const T* ptr, long count, pk_membucket* bucket = nullptr)
static inline void pkmem_stupid_header_warnings() { (void)stdout; }
#if defined(PK_MEMORY_DEBUGGER)
-/*
- * Note that certain aspects of this expect that you only have one non-transient bucket.
- * If you need to track multiple non-transient buckets, these sections will need a refactor.
- */
#endif
-#ifndef PK_MAX_BUCKET_COUNT
-# define PK_MAX_BUCKET_COUNT 8
-#endif
+#define EXPECTED_PK_MEMBLOCK_SIZE 128
+
+#define pk_memblock_blocks_idx(bkt, idx) ((bkt->block_capacity-1)-(idx))
+#define pk_bkt_data(bkt) ((char*)bkt + EXPECTED_PK_MEMBLOCK_SIZE)
+#define pk_bkt_head(bkt) ((&bkt->data[0]) + bkt->head)
+#define pk_bkt_data_sz(bkt) (size_t)((char*)&bkt->blocks[0] - &bkt->data[0])
struct pk_memblock {
- char* data;
+ union {
+ char* data;
+ void* ptr;
+ };
size_t size;
};
struct pk_membucket {
- // the total size of the bucket, `blocks+ptr`
+ // 00
+ mtx_t mtx;
+ // 40
+ // the total size of the bucket, struct+data
size_t size;
- // the current head of the bucket: byte offset from `ptr`.
+ // 48
+ // the current head of the bucket: byte offset from `data`.
// All currently alloc'd data is before this offset
size_t head;
- // amount of lost bytes in this membucket, hopefully zero
- size_t lostBytes;
+ // 56
+ uint32_t block_capacity;
+ // 60
+ uint32_t block_head_l;
+ // 64
+ // this should ALWAYS point to the last block containing unalloced space in bkt
+ uint32_t block_head_r;
+ // 68
// the number of active allocations from this bucket
- size_t allocs;
- // the index of the last empty block.
- // Should always point to `pk_memblock{ .data = ptr+head, .size=size-head }`
- size_t lastEmptyBlockIndex;
- // number of pk_memblocks in the `*blocks` array
- size_t maxBlockCount;
- // ptr to an array of pk_memblock to track ALL free space between ptr and ptr+sz
- struct pk_memblock* blocks;
+ // -should correlate to blocks that have a sz > 0
+ uint32_t alloc_count;
+ // 72
+ struct pk_memblock *blocks;
+ // 80
+ enum PK_MEMBUCKET_FLAGS flags;
+ // 88
+ const char *description;
+ // 96
+#ifdef PK_MEMORY_DEBUGGER
+ uint32_t debug_bkt_index;
+ // 100
+ uint32_t debug_head_l;
+ // 104
+ uint32_t debug_head_r;
+ // 108
+ char padding[4+(8*1)];
+ // 120
+ size_t debug_block_capacity;
+#else
+ char padding[8*4];
+#endif
+ // 128
// starting point for alloc'd data
- union {
- char* ptr;
- void* raw;
- };
- const char* description;
- mtx_t mtx;
- bool transient;
+ // data[] is illegal in c++ (though it works in gcc/clang, but so does this)
+ char data[1];
};
-static struct pk_membucket pk_buckets[PK_MAX_BUCKET_COUNT];
-static size_t pk_bucket_head = 0;
+static struct pk_membucket *client_bucket = NULL;
#ifdef PK_MEMORY_DEBUGGER
#include <stdatomic.h>
-struct pk_dbg_memblock {
- struct pk_memblock blk;
- struct pk_membucket *bkt;
-};
-static struct pk_dbg_memblock debug_all_allocs[1024 * 1024];
-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;
+static struct pk_memblock *debug_allocs[16];
+static size_t debug_alloc_head = 0;
+static mtx_t debug_mtx;
#endif
+size_t
+pk_mem_calculate_bkt_size(size_t sz, size_t reserved_block_count)
+{
+ size_t base_size = EXPECTED_PK_MEMBLOCK_SIZE + sz + (sizeof(struct pk_memblock) * reserved_block_count);
+ // This trick ensures that our array of pk_memblocks at the end is mem-aligned.
+ // We do, however, still have to do the math when setting the ptr.
+ // Why? the user may have strict memory requirements and didn't call this function.
+ return base_size + (64 - (base_size % 64));
+}
+
bool
pk_memory_is_in_bucket(const void* ptr, const struct pk_membucket* bkt)
{
- if (ptr >= bkt->raw && (const char*)ptr < bkt->ptr + bkt->size) return true;
- return false;
+ return (ptr >= (void*)bkt && ptr < (void*)pk_bkt_head(bkt));
}
void
-pk_memory_debug_print()
+pk_memory_debug_print(struct pk_membucket *bkt)
{
- size_t i;
-#ifdef PK_MEMORY_DEBUGGER
- size_t d;
- size_t count = 0;
- 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) {
- PK_LOGV_INF("- bucket #%li\n", i);
- PK_LOGV_INF("\tdescription: %s\n", pk_buckets[i].description);
- PK_LOGV_INF("\tsize: %li\n", pk_buckets[i].size);
- PK_LOGV_INF("\thead: %li\n", pk_buckets[i].head);
- PK_LOGV_INF("\tlostBytes: %li\n", pk_buckets[i].lostBytes);
- PK_LOGV_INF("\tallocs: %li\n", pk_buckets[i].allocs);
- PK_LOGV_INF("\tlastEmptyBlockIndex: %li\n", pk_buckets[i].lastEmptyBlockIndex);
- PK_LOGV_INF("\tmaxBlockCount: %li\n", pk_buckets[i].maxBlockCount);
- PK_LOGV_INF("\tblocks: %p\n", (void *)pk_buckets[i].blocks);
- PK_LOGV_INF("\tptr: %p\n", (void *)pk_buckets[i].ptr);
- PK_LOGV_INF("\ttransient: %i\n", pk_buckets[i].transient);
+ PK_LOG_INF("pk_membucket details:\n");
+ PK_LOGV_INF("\tbkt: %p\n", (void *)bkt);
+ PK_LOGV_INF("\tdescription: %s\n", bkt->description);
+ PK_LOGV_INF("\tsize: %lu\n", bkt->size);
+ PK_LOGV_INF("\thead: %lu\n", bkt->head);
+ PK_LOGV_INF("\tallocs: %u\n", bkt->alloc_count);
+ PK_LOGV_INF("\tblock head_l: %u\n", bkt->block_head_l);
+ PK_LOGV_INF("\tblock head_r: %u\n", bkt->block_head_r);
+ PK_LOGV_INF("\tflags: %lu\n", bkt->flags);
#ifdef PK_MEMORY_DEBUGGER
- 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 head_l: %lu\n", dahl);
- PK_LOGV_INF("\tdebug alloc head_r: %lu\n", dahr);
+ PK_LOGV_INF("\tdebug index: %u\n", bkt->debug_bkt_index);
+ PK_LOGV_INF("\tdebug alloc head_l: %u\n", bkt->debug_head_l);
+ PK_LOGV_INF("\tdebug alloc head_r: %u\n", bkt->debug_head_r);
+ PK_LOGV_INF("\tdebug cappacity: %lu\n", bkt->debug_block_capacity);
#endif
- }
-}
-
-void
-pk_memory_flush()
-{
- for (long i = pk_bucket_head - 1; i > -1; --i) {
- if (pk_buckets[i].head != 0) break;
- if (pk_buckets[i].transient == true) break;
- pk_bucket_head--;
- if (pk_buckets[i].raw == CAFE_BABE(void)) continue;
- pk_bucket_destroy(&pk_buckets[i]);
- }
}
void
pk_memory_teardown_all()
{
- for (int64_t i = pk_bucket_head; i > 0; --i) {
- if (pk_buckets[i - 1].ptr == nullptr) continue;
- if (pk_buckets[i - 1].ptr == CAFE_BABE(char)) continue;
- pk_bucket_destroy(&pk_buckets[i - 1]);
- }
- pk_bucket_head = 0;
+ client_bucket = NULL;
#ifdef PK_MEMORY_DEBUGGER
- debug_alloc_head_l = 0;
- debug_alloc_head_r = 0;
- mtx_destroy(&debug_alloc_mtx);
- has_init_debug = false;
+ mtx_lock(&debug_mtx);
+ for (size_t i = 0; i < debug_alloc_head; ++i) {
+ if (debug_allocs[i] != NULL) {
+ free(debug_allocs[i]);
+ }
+ debug_allocs[i] = NULL;
+ }
+ debug_alloc_head = 0;
+ mtx_unlock(&debug_mtx);
#endif
}
-static int64_t
-pk_bucket_create_inner(int64_t sz, bool transient, const char* description)
+struct pk_membucket*
+pk_bucket_create(const char* description, int64_t sz, enum PK_MEMBUCKET_FLAGS flags)
{
- if (pk_bucket_head >= PK_MAX_BUCKET_COUNT) return -1;
-#ifdef PK_MEMORY_DEBUGGER
- if (has_init_debug == false) {
- has_init_debug = true;
- mtx_init(&debug_alloc_mtx, mtx_plain);
- }
-#endif
- int64_t blockCount = sz * 0.01;
- struct pk_membucket* bkt = &pk_buckets[pk_bucket_head];
+ // 512 example:
+ // [000-127] pk_membucket
+ // [128-191] 64 bytes of data LOL
+ // [192-511] 20 pk_memblocks (20 is worst-case, start 16, 4 per 64 bytes)
+ assert(sz >= 512 && "[pkmem.h] bucket too small to track allocation data");
+ struct pk_membucket* bkt = (struct pk_membucket*)aligned_alloc(64, sz);
+ if (bkt == NULL) return NULL;
+ mtx_init(&bkt->mtx, mtx_plain);
bkt->size = sz;
bkt->head = 0;
- bkt->lostBytes = 0;
- bkt->allocs = 0;
- bkt->lastEmptyBlockIndex = 0;
- bkt->maxBlockCount = blockCount < 10 ? 10 : blockCount;
- bkt->blocks = (struct pk_memblock*)malloc(sz);
- mtx_init(&bkt->mtx, mtx_plain);
- assert(bkt->blocks != nullptr && "failed to allocate memory");
- bkt->ptr = ((char*)(bkt->blocks)) + (sizeof(struct pk_memblock) * bkt->maxBlockCount);
- size_t misalignment = (size_t)(bkt->ptr) % PK_MAXIMUM_ALIGNMENT;
- if (misalignment != 0) {
- size_t moreBlocks = misalignment / sizeof(struct pk_memblock);
- bkt->maxBlockCount += moreBlocks;
- bkt->ptr += (PK_MAXIMUM_ALIGNMENT - misalignment);
- }
+ bkt->block_capacity = 16;
+ bkt->block_head_l = 0;
+ bkt->block_head_r = 0;
+ bkt->alloc_count = 0;
+ bkt->flags = flags;
bkt->description = description;
- bkt->transient = transient;
- struct pk_memblock* memBlock = (struct pk_memblock*)(bkt->blocks);
- memBlock->data = bkt->ptr;
- memBlock->size = sz - (sizeof(struct pk_memblock) * bkt->maxBlockCount);
- return pk_bucket_head++;
-}
+ char* blocks_addr = (char*)bkt + sz - (sizeof(struct pk_memblock) * bkt->block_capacity);
+ blocks_addr -= (size_t)blocks_addr % 64;
+ bkt->blocks = (struct pk_memblock*)blocks_addr;
+ bkt->block_capacity = (size_t)(((char*)bkt + sz) - blocks_addr) / sizeof(struct pk_memblock);
-struct pk_membucket*
-pk_bucket_create(const char* description, int64_t sz, bool transient)
-{
- int64_t bkt_index = pk_bucket_create_inner(sz, transient, description);
- // TODO some of of error handling
- if (bkt_index < 0) { return nullptr; }
- return &pk_buckets[bkt_index];
+ bkt->blocks[pk_memblock_blocks_idx(bkt,0)].size = pk_bkt_data_sz(bkt);
+ bkt->blocks[pk_memblock_blocks_idx(bkt,0)].ptr = pk_bkt_data(bkt);
+
+#ifdef PK_MEMORY_DEBUGGER
+ mtx_lock(&debug_mtx);
+ bkt->debug_bkt_index = debug_alloc_head++;
+ mtx_unlock(&debug_mtx);
+ bkt->debug_head_l = 0;
+ bkt->debug_head_r = 0;
+ bkt->debug_block_capacity = 128;
+ debug_allocs[bkt->debug_bkt_index] = (struct pk_memblock*)aligned_alloc(alignof(struct pk_memblock), sizeof(struct pk_memblock) * 128);
+#endif
+
+ return bkt;
}
void
pk_bucket_destroy(struct pk_membucket* bkt)
{
- size_t i;
- for (i = 0; i < pk_bucket_head; ++i) {
- if (&pk_buckets[i] == bkt) {
- if (pk_bucket_head == i + 1)
- pk_bucket_head--;
- break;
- }
- }
- if (bkt->blocks != NULL && bkt->blocks != CAFE_BABE(struct pk_memblock)) free(bkt->blocks);
- bkt->size = 0;
- bkt->head = 0;
- bkt->lostBytes = 0;
- bkt->allocs = 0;
- bkt->lastEmptyBlockIndex = 0;
- bkt->maxBlockCount = 0;
- bkt->blocks = CAFE_BABE(struct pk_memblock);
- bkt->ptr = CAFE_BABE(char);
- bkt->transient = false;
- mtx_destroy(&bkt->mtx);
+ assert(bkt != NULL);
#ifdef PK_MEMORY_DEBUGGER
- 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;
+ mtx_lock(&debug_mtx);
+ assert(bkt->debug_bkt_index <= debug_alloc_head);
+ if (debug_allocs[bkt->debug_bkt_index] != NULL) free(debug_allocs[bkt->debug_bkt_index]);
+ debug_allocs[bkt->debug_bkt_index] = NULL;
+ while (debug_alloc_head > 0) {
+ if (debug_allocs[debug_alloc_head-1] != NULL) {
+ break;
}
+ debug_alloc_head--;
}
- 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);
+ mtx_unlock(&debug_mtx);
#endif
+ free(bkt);
}
void
pk_bucket_reset(struct pk_membucket* bkt)
{
-#ifdef PK_MEMORY_DEBUGGER
- size_t i;
-#endif
- if (bkt->transient != true) {
+ if (PK_HAS_FLAG(bkt->flags, PK_MEMBUCKET_FLAG_TRANSIENT) == true) {
PK_LOG_ERR("WARNING: pk_bucket_reset called on non-transient pk_membucket\n");
}
bkt->head = 0;
- bkt->lostBytes = 0;
- bkt->allocs = 0;
- bkt->lastEmptyBlockIndex = 0;
- bkt->blocks->data = bkt->ptr;
- bkt->blocks->size = bkt->size - (sizeof(struct pk_memblock) * bkt->maxBlockCount);
+ bkt->block_capacity = 16;
+ char* blocks_addr = (char*)bkt + bkt->size - (sizeof(struct pk_memblock) * bkt->block_capacity);
+ blocks_addr -= (size_t)blocks_addr % 64;
+ bkt->blocks = (struct pk_memblock*)blocks_addr;
+ bkt->block_capacity = (size_t)(((char*)bkt + bkt->size) - blocks_addr) / sizeof(struct pk_memblock);
+ bkt->block_head_l = 0;
+ bkt->block_head_r = 0;
+ bkt->alloc_count = 0;
+
+ bkt->blocks[pk_memblock_blocks_idx(bkt,0)].size = pk_bkt_data_sz(bkt);
+ bkt->blocks[pk_memblock_blocks_idx(bkt,0)].ptr = pk_bkt_data(bkt);
+
#ifdef PK_MEMORY_DEBUGGER
- 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);
+ bkt->debug_head_l = 0;
+ bkt->debug_head_r = 0;
#endif
}
+void pk_bucket_set_client_bucket(struct pk_membucket *bkt) {
+ client_bucket = bkt;
+}
+
void
pk_bucket_insert_block(struct pk_membucket* bkt, const struct pk_memblock* block)
{
- int64_t index = bkt->lastEmptyBlockIndex;
- while (index >= 0) {
- struct pk_memblock* b = &bkt->blocks[index];
- struct pk_memblock* nb = &bkt->blocks[index + 1];
- if (b->data < block->data) {
+ // 2025-06-03 JCB
+ // Note that this function should only be called if we're INSERTING.
+ // This means that the block will never go at the END of the list - that would be an append.
+ // It can, however, be placed at the beginning, in which case the entire array shifts.
+
+ struct pk_memblock* new_block;
+ struct pk_memblock* old_block;
+ size_t i, k;
+
+ // 1. resize if needed
+ if (bkt->block_head_r+1 == bkt->block_capacity) {
+ if (bkt->blocks[pk_memblock_blocks_idx(bkt, bkt->block_head_r)].size < sizeof(struct pk_memblock)) {
+ PK_LOG_ERR("[pkmem.h] bkt out of memory when expanding memory blocks.");
+ exit(1);
+ }
+ // this is all that needs done, arr can just grow like this
+ bkt->blocks[pk_memblock_blocks_idx(bkt, bkt->block_head_r)].size -= sizeof(struct pk_memblock);
+ bkt->block_capacity += 1;
+ bkt->blocks -= 1;
+ }
+
+ // 2. move all blocks forward until we pass the pointer
+ // reminder that these blocks are in REVERSE order
+ for (i = bkt->block_head_r+1; i > 0; --i) {
+ k = pk_memblock_blocks_idx(bkt, i);
+ new_block = &bkt->blocks[k];
+ old_block = new_block+1;
+ *new_block = *old_block;
+ if (old_block->data < block->data) {
break;
}
- nb->data = b->data;
- nb->size = b->size;
- index -= 1;
}
- struct pk_memblock *b = &bkt->blocks[index + 1];
- b->data = block->data;
- b->size = block->size;
- bkt->lastEmptyBlockIndex += 1;
+ if (i == 0) {
+ *old_block = *block;
+ } else {
+ *new_block = *block;
+ }
+ bkt->block_head_r += 1;
}
void
-pk_bucket_collapse_empty_blocks(struct pk_membucket* bkt)
+pk_bucket_collapse_blocks(struct pk_membucket* bkt)
{
- size_t i, ii;
- for (ii = bkt->lastEmptyBlockIndex+1; ii > 0; --ii) {
- i = ii-1;
- struct pk_memblock* block = &bkt->blocks[i];
- if (block->size == 0 && i == bkt->lastEmptyBlockIndex) {
- block->data = nullptr;
- bkt->lastEmptyBlockIndex -= 1;
- continue;
- }
- if (block->size > 0) {
- continue;
- }
- for (size_t k = i; k < bkt->lastEmptyBlockIndex; ++k) {
- bkt->blocks[k].data = bkt->blocks[k + 1].data;
- bkt->blocks[k].size = bkt->blocks[k + 1].size;
- }
- bkt->lastEmptyBlockIndex -= 1;
+ // 1. loop through from (rev_idx)0 to head_r, shifting any blocks that have size 0
+ struct pk_memblock* new_block;
+ struct pk_memblock* old_block;
+ size_t i, ii, bhr;
+ // there's an off by one annoynce here
+ // start with ii = 0
+ // if we start with ii = 1, we might subtract from block_head_r when nothing was shifted
+ for (i = 0, ii = 0, bhr = bkt->block_head_r; (i + ii) <= bhr; ++i) {
+ new_block = &bkt->blocks[pk_memblock_blocks_idx(bkt, i)];
+ if (new_block->size > 0) continue;
+ do {
+ old_block = new_block - ii;
+ if (old_block->size == 0) {
+ ii+=1;
+ } else {
+ break;
+ }
+ } while (i + ii <= bhr);
+ *new_block = *old_block;
+ old_block->size = 0;
+ old_block->ptr = NULL;
}
+ bkt->block_head_r -= ii;
}
void*
@@ -431,107 +411,86 @@ pk_new_bkt(size_t sz, size_t alignment, struct pk_membucket* bkt)
#ifdef PK_MEMORY_FORCE_MALLOC
return malloc(sz);
#endif
- if (sz == 0) return nullptr;
- if (bkt == nullptr) return nullptr;
+ if (sz == 0) return NULL;
+ if (bkt == NULL) return NULL;
// TODO some type of error handling
- if ((bkt->size - bkt->head) < (sz + alignment - 1)) return nullptr;
- size_t i;
+ if ((bkt->size - bkt->head) < (sz + alignment - 1)) return NULL;
+ size_t i, k;
size_t calculatedAlignment = alignment < PK_MINIMUM_ALIGNMENT ? PK_MINIMUM_ALIGNMENT : alignment;
size_t misalignment = 0;
- struct pk_memblock* prevBlock = nullptr;
- struct pk_memblock* block = nullptr;
- struct pk_memblock* nextBlock = nullptr;
- void* data = nullptr;
+ struct pk_memblock tmp_blk;
+ struct pk_memblock* block = NULL;
+ void* data = NULL;
mtx_lock(&bkt->mtx);
- for (i = 0; i <= bkt->lastEmptyBlockIndex; ++i) {
- struct pk_memblock* blk = &bkt->blocks[i];
- misalignment = (size_t)(blk->data) % calculatedAlignment;
+
+ // find block
+ for (i = 0; i <= bkt->block_head_r; ++i) {
+ k = pk_memblock_blocks_idx(bkt, i);
+ tmp_blk = bkt->blocks[k];
+ misalignment = (size_t)(tmp_blk.data) % calculatedAlignment;
misalignment = (calculatedAlignment - misalignment) % calculatedAlignment;
- if (blk->size >= sz + misalignment) {
- block = blk;
- if (i < bkt->lastEmptyBlockIndex && bkt->blocks[i + 1].data == block->data + block->size) {
- nextBlock = &bkt->blocks[i + 1];
- }
- if (i > 0 && i != bkt->lastEmptyBlockIndex && (bkt->blocks[i-1].data + bkt->blocks[i-1].size) == block->data) {
- prevBlock = &bkt->blocks[i - 1];
- }
- break;
+ if (tmp_blk.size < sz + misalignment) {
+ continue;
}
+ block = &bkt->blocks[k];
+ break;
}
- if (block == nullptr) {
+ if (block == NULL) {
mtx_unlock(&bkt->mtx);
- assert(block != nullptr && "memory corruption: not enough space in chosen bkt");
+ assert(block != NULL && "memory corruption: not enough space in chosen bkt");
}
data = block->data + misalignment;
#ifdef PK_MEMORY_DEBUGGER
- 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 (PK_HAS_FLAG(bkt->flags, PK_MEMBUCKET_FLAG_TRANSIENT) == false) {
+ for (i = 0; i < bkt->debug_head_r; ++i) {
+ assert((debug_allocs[bkt->debug_bkt_index][i].size == 0 || (void*)(debug_allocs[bkt->debug_bkt_index][i].data) != data) && "mem address alloc'd twice!");
}
- mtx_lock(&debug_alloc_mtx);
- i = debug_alloc_head_l;
- if (debug_alloc_head_l == debug_alloc_head_r) {
- debug_alloc_head_l++;
- debug_alloc_head_r++;
+ i = bkt->debug_head_l;
+ if (bkt->debug_head_l == bkt->debug_head_r) {
+ bkt->debug_head_l++;
+ bkt->debug_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;
+ for (ii = bkt->debug_head_l+1; ii <= bkt->debug_head_r; ++ii) {
+ if (debug_allocs[bkt->debug_bkt_index][ii].size == 0) {
+ bkt->debug_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;
- debug_all_allocs[i].bkt = bkt;
+ assert(bkt->debug_head_l <= bkt->debug_head_r);
+ debug_allocs[bkt->debug_bkt_index][i].data = (char*)data;
+ debug_allocs[bkt->debug_bkt_index][i].size = sz;
}
#endif
- int64_t afterSize = block->size - (misalignment + sz);
- if (block->data == bkt->ptr + bkt->head) {
+ if (block->data == pk_bkt_head(bkt)) {
bkt->head += (sz + misalignment);
}
- if (afterSize > 0 && nextBlock == nullptr) {
- struct pk_memblock newBlock;
- memset(&newBlock, 0, sizeof(struct pk_memblock));
- newBlock.data = block->data + misalignment + sz;
- newBlock.size = afterSize;
- pk_bucket_insert_block(bkt, &newBlock);
- }
- if (prevBlock == nullptr && nextBlock == nullptr) {
- block->size = misalignment;
- } else if (nextBlock != nullptr) {
- block->size = misalignment;
- nextBlock->data -= afterSize;
- nextBlock->size += afterSize;
- } else if (prevBlock != nullptr) {
- prevBlock->size += misalignment;
- block->data += misalignment + sz;
- block->size = 0; // if you make it here, afterSize has already been handled
- } else {
- assert(true == false && "this shouldn't happen");
+
+ tmp_blk.data = block->data;
+ tmp_blk.size = misalignment;
+ block->data += misalignment + sz;
+ block->size -= misalignment + sz;
+
+ if (tmp_blk.size > 0) {
+ pk_bucket_insert_block(bkt, &tmp_blk);
}
- bkt->allocs++;
- assert(data >= bkt->raw && "allocated data is before bucket data");
- assert((char*)data <= bkt->ptr + bkt->size && "allocated data is after bucket data");
- pk_bucket_collapse_empty_blocks(bkt);
+ pk_bucket_collapse_blocks(bkt);
+
+ bkt->alloc_count++;
+ assert(data >= (void*)pk_bkt_data(bkt) && "allocated data is before bucket data");
+ assert((char*)data <= pk_bkt_data(bkt) + bkt->size && "allocated data is after bucket data");
#ifdef PK_MEMORY_DEBUGGER
- if (!bkt->transient) {
+ if (PK_HAS_FLAG(bkt->flags, PK_MEMBUCKET_FLAG_TRANSIENT) == false) {
+ size_t k;
int64_t debug_tracked_alloc_size = 0;
- int64_t debug_bucket_alloc_size = bkt->size - (sizeof(struct pk_memblock) * bkt->maxBlockCount);
- 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;
+ int64_t debug_bucket_alloc_size = pk_bkt_data_sz(bkt);
+ for (i = 0; i < bkt->debug_head_r; ++i) {
+ debug_tracked_alloc_size += debug_allocs[bkt->debug_bkt_index][i].size;
}
- for (i = 0; i <= bkt->lastEmptyBlockIndex; ++i) {
- debug_bucket_alloc_size -= bkt->blocks[i].size;
+ for (i = 0; i <= bkt->block_head_r; ++i) {
+ k = pk_memblock_blocks_idx(bkt, i);
+ debug_bucket_alloc_size -= bkt->blocks[k].size;
}
assert(debug_tracked_alloc_size == debug_bucket_alloc_size && "allocation size mismatch!");
}
@@ -544,23 +503,8 @@ pk_new_bkt(size_t sz, size_t alignment, struct pk_membucket* bkt)
void*
pk_new_base(size_t sz, size_t alignment)
{
- struct pk_membucket* bkt = nullptr;
- for (size_t i = 0; i < pk_bucket_head; ++i) {
- if (pk_buckets[i].transient == true) {
- continue;
- }
- if (pk_buckets[i].size - pk_buckets[i].head < sz + (alignment - 1)) {
- continue;
- }
- bkt = &pk_buckets[i];
- break;
- }
- if (bkt == nullptr) {
- int64_t bkt_index = pk_bucket_create_inner(PK_DEFAULT_BUCKET_SIZE, false, "pk_bucket internally created");
- // TODO some of of error handling
- if (bkt_index >= 0) bkt = &pk_buckets[bkt_index];
- }
- return pk_new_bkt(sz, alignment, bkt);
+ if (client_bucket == NULL) return NULL;
+ return pk_new_bkt(sz, alignment, client_bucket);
}
void*
@@ -580,102 +524,112 @@ pk_delete_bkt(const void* ptr, size_t sz, struct pk_membucket* bkt)
return free((void*)ptr);
#endif
#endif
- size_t i;
+ size_t i, k;
mtx_lock(&bkt->mtx);
- assert(bkt->allocs > 0);
- assert(ptr >= bkt->raw && (char*)ptr < bkt->ptr + bkt->size && "pointer not in memory bucket range");
+ assert(bkt->alloc_count > 0);
+ assert(pk_memory_is_in_bucket(ptr, bkt) && "pointer not in memory bucket range");
assert(sz > 0 && "attempted to free pointer of size 0");
#ifdef PK_MEMORY_DEBUGGER
- bool found = bkt->transient;
- struct pk_dbg_memblock* mb;
- mtx_lock(&debug_alloc_mtx);
+ bool found = PK_HAS_FLAG(bkt->flags, PK_MEMBUCKET_FLAG_TRANSIENT);
+ struct pk_memblock *debug_memblocks = debug_allocs[bkt->debug_bkt_index];
+ struct pk_memblock *mb;
if (found == false) {
- 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) {
- assert(mb->blk.size == sz && "[pkmem.h] incorrect free size");
- mb->blk.size = 0;
- mb->bkt = NULL;
+ for (i = bkt->debug_head_r+1; i > 0; --i) {
+ mb = &debug_memblocks[i-1];
+ if (mb->size == 0) continue;
+ if ((void*)(mb->ptr) == ptr) {
+ assert(mb->size == sz && "[pkmem.h] incorrect free size");
+ mb->ptr = NULL;
+ mb->size = 0;
found = true;
- if (i <= debug_alloc_head_l) {
- debug_alloc_head_l = i-1;
+ if (i <= bkt->debug_head_l) {
+ bkt->debug_head_l = i-1;
}
- if (i == debug_alloc_head_r) {
- debug_alloc_head_r--;
+ if (i == bkt->debug_head_r) {
+ bkt->debug_head_r--;
}
-#ifdef PK_MEMORY_DEBUGGER_L2
- assert(debug_alloc_head_l <= debug_alloc_head_r);
-#endif
+ assert(bkt->debug_head_l <= bkt->debug_head_r);
break;
}
}
}
- mtx_unlock(&debug_alloc_mtx);
assert(found && "[pkmem.h] double free or invalid ptr");
#endif
- bkt->allocs--;
- if (bkt->allocs == 0) {
+ bkt->alloc_count--;
+ if (bkt->alloc_count == 0) {
bkt->head = 0;
- bkt->lastEmptyBlockIndex = 0;
- bkt->blocks[0].data = bkt->ptr;
- bkt->blocks[0].size = bkt->size - (sizeof(struct pk_memblock) * bkt->maxBlockCount);
+ bkt->block_head_l = 0;
+ bkt->block_head_r = 0;
+ bkt->blocks[0].data = pk_bkt_data(bkt);
+ bkt->blocks[0].size = pk_bkt_data_sz(bkt);
+#ifdef PK_MEMORY_DEBUGGER
+ bkt->debug_head_l = 0;
+ bkt->debug_head_r = 0;
+ debug_allocs[bkt->debug_bkt_index][0].data = NULL;
+ debug_allocs[bkt->debug_bkt_index][0].size = 0;
+#endif
mtx_unlock(&bkt->mtx);
return;
}
char* afterPtr = ((char*)(ptr))+sz;
- struct pk_memblock* beforeBlk = nullptr;
- struct pk_memblock* afterBlk = nullptr;
- for (i = bkt->lastEmptyBlockIndex; i > 0; --i) {
- if (bkt->blocks[i-1].data + bkt->blocks[i-1].size == ptr) {
- beforeBlk = &bkt->blocks[i-1];
+ struct pk_memblock* tmp_blk = NULL;
+ struct pk_memblock* beforeBlk = NULL;
+ struct pk_memblock* afterBlk = NULL;
+ for (i = bkt->block_head_r+1; i > 0 ; --i) {
+ k = pk_memblock_blocks_idx(bkt, i-2);
+ tmp_blk = &bkt->blocks[k];
+ if (tmp_blk->data + tmp_blk->size == ptr) {
+ beforeBlk = tmp_blk;
}
- if (bkt->blocks[i].data == afterPtr) {
- afterBlk = &bkt->blocks[i];
+ tmp_blk -= 1;
+ if (i <= bkt->block_head_r+1 && tmp_blk->data == afterPtr) {
+ afterBlk = tmp_blk;
break;
}
- if (bkt->blocks[i-1].data < (char*)ptr) {
+ tmp_blk += 1;
+ if (tmp_blk->data < (char*)ptr) {
break;
}
}
- if (ptr == bkt->ptr && afterBlk == nullptr && bkt->blocks[0].data == afterPtr) {
- afterBlk = &bkt->blocks[0];
+ if (ptr == &bkt->data[0] && afterBlk == NULL && bkt->blocks[pk_memblock_blocks_idx(bkt, 0)].data == afterPtr) {
+ afterBlk = &bkt->blocks[pk_memblock_blocks_idx(bkt, 0)];
}
- if (afterBlk != nullptr && afterBlk->data == bkt->ptr + bkt->head) {
+ if (afterBlk != NULL && afterBlk->data == pk_bkt_head(bkt)) {
bkt->head -= sz;
- if (beforeBlk != nullptr) {
+ if (beforeBlk != NULL) {
bkt->head -= beforeBlk->size;
}
}
- if (beforeBlk == nullptr && afterBlk == nullptr) {
+ if (beforeBlk == NULL && afterBlk == NULL) {
struct pk_memblock newBlock;
memset(&newBlock, 0, sizeof(struct pk_memblock));
newBlock.data = (char*)ptr;
newBlock.size = sz;
pk_bucket_insert_block(bkt, &newBlock);
- } else if (beforeBlk != nullptr && afterBlk != nullptr) {
+ } else if (beforeBlk != NULL && afterBlk != NULL) {
beforeBlk->size += sz + afterBlk->size;
+ if (beforeBlk->data == pk_bkt_head(bkt)) {
+ bkt->block_head_r--;
+ }
afterBlk->size = 0;
- } else if (beforeBlk != nullptr) {
+ afterBlk->data = NULL;
+ } else if (beforeBlk != NULL) {
beforeBlk->size += sz;
- } else if (afterBlk != nullptr) {
+ } else if (afterBlk != NULL) {
afterBlk->data -= sz;
afterBlk->size += sz;
}
- pk_bucket_collapse_empty_blocks(bkt);
+ pk_bucket_collapse_blocks(bkt);
#ifdef PK_MEMORY_DEBUGGER
- if (!bkt->transient) {
+ if (PK_HAS_FLAG(bkt->flags, PK_MEMBUCKET_FLAG_TRANSIENT) == false) {
int64_t debug_tracked_alloc_size = 0;
- int64_t debug_bucket_alloc_size = bkt->size - (sizeof(struct pk_memblock) * bkt->maxBlockCount);
- 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;
+ int64_t debug_bucket_alloc_size = pk_bkt_data_sz(bkt);
+ for (i = 0; i < bkt->debug_head_r; ++i) {
+ debug_tracked_alloc_size += debug_allocs[bkt->debug_bkt_index][i].size;
}
- for (i = 0; i <= bkt->lastEmptyBlockIndex; ++i) {
- debug_bucket_alloc_size -= bkt->blocks[i].size;
+ for (i = 0; i <= bkt->block_head_r; ++i) {
+ k = pk_memblock_blocks_idx(bkt, i);
+ debug_bucket_alloc_size -= bkt->blocks[k].size;
}
assert(debug_tracked_alloc_size == debug_bucket_alloc_size && "allocation size mismatch!");
}
@@ -686,13 +640,7 @@ pk_delete_bkt(const void* ptr, size_t sz, struct pk_membucket* bkt)
void
pk_delete_base(const void* ptr, size_t sz)
{
- struct pk_membucket* bkt = nullptr;
- for (size_t i = 0; i < pk_bucket_head; ++i) {
- bkt = &pk_buckets[i];
- if (ptr >= bkt->raw && (char*)ptr < bkt->ptr + bkt->size) break;
- }
- assert(bkt != nullptr && "failed to determine correct memory bucket");
- pk_delete_bkt(ptr, sz, bkt);
+ pk_delete_bkt(ptr, sz, client_bucket);
}
void
diff --git a/test/pkmem.c b/test/pkmem.c
index 252428d..7614379 100644
--- a/test/pkmem.c
+++ b/test/pkmem.c
@@ -38,6 +38,7 @@ int main(int argc, char *argv[])
// pk_new_base
{
spinup_w_instr();
+ pk_bucket_set_client_bucket(mt.bkt1);
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);
@@ -64,9 +65,9 @@ int main(int argc, char *argv[])
if (zero_length_string != NULL) exit(1);
if (strlen(three_length_string) != 2) exit(1);
- if (mt.bkt1->allocs != 1) exit(1);
+ if (mt.bkt1->alloc_count != 1) exit(1);
if (mt.bkt1->head != 3) exit(1);
- if (mt.bkt1->lastEmptyBlockIndex != 0) exit(1);
+ if (mt.bkt1->block_head_r != 0) exit(1);
PK_LOGV_INF("%s: %s\n", __FILE__, "handles zero-length alloc");
teardown();
diff --git a/test/pkmem.cpp b/test/pkmem.cpp
index 98d2dd2..6a52f25 100644
--- a/test/pkmem.cpp
+++ b/test/pkmem.cpp
@@ -21,7 +21,9 @@ class FreeTest {
void *ptrs[4];
FreeTest() :
- bkt(pk_bucket_create("freetest", 1024 * 1024, false)) { }
+ bkt(pk_bucket_create("freetest", 1024 * 1024, PK_MEMBUCKET_FLAG_NONE)) {
+ pk_bucket_set_client_bucket(this->bkt);
+ }
virtual ~FreeTest() {
pk_bucket_destroy(this->bkt);
}
@@ -55,12 +57,12 @@ class FreeTest01 : public FreeTest {
virtual ~FreeTest01() {}
virtual void ensureState() override {
- pk_mem_assert(3 == bkt->lastEmptyBlockIndex);
+ pk_mem_assert(3 == bkt->block_head_r);
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]);
+ pk_mem_assert(&bkt->data[0] + 00 == ptrs[0]);
+ pk_mem_assert(&bkt->data[0] + 64 == ptrs[1]);
+ pk_mem_assert(&bkt->data[0] + 16 == ptrs[2]);
+ pk_mem_assert(&bkt->data[0] + 8 == ptrs[3]);
}
};
@@ -89,17 +91,17 @@ class FreeTest02 : public FreeTest {
virtual ~FreeTest02() {}
virtual void ensureState() override {
- pk_mem_assert(2 == bkt->lastEmptyBlockIndex);
+ pk_mem_assert(2 == bkt->block_head_r);
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]);
+ pk_mem_assert(&bkt->data[0] + 00 == ptrs[0]);
+ pk_mem_assert(&bkt->data[0] + 64 == ptrs[1]);
+ pk_mem_assert(&bkt->data[0] + 32 == ptrs[2]);
- pk_mem_assert(bkt->ptr + 19 == bkt->blocks[0].data);
- pk_mem_assert(13 == bkt->blocks[0].size);
+ pk_mem_assert(&bkt->data[0] + 19 == bkt->blocks[15].data);
+ pk_mem_assert(13 == bkt->blocks[15].size);
- pk_mem_assert(bkt->ptr + 33 == bkt->blocks[1].data);
- pk_mem_assert(31 == bkt->blocks[1].size);
+ pk_mem_assert(&bkt->data[0] + 33 == bkt->blocks[14].data);
+ pk_mem_assert(31 == bkt->blocks[14].size);
}
};
@@ -162,15 +164,36 @@ int main(int argc, char *argv[])
// signal(SIGABRT, handle_assert_abort);
(void)argc;
(void)argv;
- int i;
+ // int i;
// pk_new<T>
pk_test_pkmem_spinup(true);
fprintf(stdout, "[pkmem.cpp] start: %s\n", test_basic_alloc);
{
+ pk_membucket *bkt = pk_bucket_create("test-some-dang-string", 1024, PK_MEMBUCKET_FLAG_NONE);
+ pk_bucket_set_client_bucket(bkt);
+
char *some_dang_string = pk_new<char>(64);
+
fprintf(stdout, "some_dang_string: %s: %p\n", some_dang_string, (void *)some_dang_string);
+
+ fprintf(stdout, "debug block : size: %zu, data: %p\n", debug_allocs[0][0].size, debug_allocs[0][0].ptr);
+ pk_mem_assert(64 == debug_allocs[0][0].size);
+ pk_mem_assert((char*)bkt + EXPECTED_PK_MEMBLOCK_SIZE == debug_allocs[0][0].data);
+
+ fprintf(stdout, "bkt->head : %lu\n", bkt->head);
+ pk_mem_assert(64 == bkt->head);
+
+ fprintf(stdout, "blocks[15].data : %p\n", bkt->blocks[15].ptr);
+ pk_mem_assert(&bkt->data[0] + 64 == bkt->blocks[15].data);
+
+ fprintf(stdout, "blocks[15].size : %li\n", bkt->blocks[15].size);
+ // 576 == 1024 - EXPECTED_PK_MEMBLOCK_SIZE - (sizeof(pk_memblock) * bkt->block_capacity) - 64
+ pk_mem_assert(576 == bkt->blocks[15].size);
+
pk_delete<char>(some_dang_string, 64);
+
+ pk_bucket_destroy(bkt);
}
pk_test_pkmem_teardown();
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_basic_alloc);
@@ -179,22 +202,25 @@ int main(int argc, char *argv[])
pk_test_pkmem_spinup(true);
fprintf(stdout, "[pkmem.cpp] start: %s\n", test_misalignment01);
{
- pk_membucket *bkt = pk_bucket_create("misalignment", 1024 * 1024, false);
+ pk_membucket *bkt = pk_bucket_create("misalignment", 1024 * 1024, PK_MEMBUCKET_FLAG_NONE);
+ pk_bucket_set_client_bucket(bkt);
pk_new(1, 1, bkt);
pk_new(1, 64, bkt);
pk_new(9, 1, bkt);
- fprintf(stdout, "lastEmptyBlockIndex: %li\n", bkt->lastEmptyBlockIndex);
- pk_mem_assert(1 == bkt->lastEmptyBlockIndex);
+ fprintf(stdout, "block_head_r: %u\n", bkt->block_head_r);
+ pk_mem_assert(1 == bkt->block_head_r);
- fprintf(stdout, "head : %li\n", bkt->head);
+ fprintf(stdout, "head : %li\n", bkt->head);
pk_mem_assert(65 == bkt->head);
- fprintf(stdout, "blocks[0].data : %p\n", (void *)bkt->blocks[0].data);
- pk_mem_assert(bkt->ptr + 10 == bkt->blocks[0].data);
+ fprintf(stdout, "blocks[15].data : %p\n", (void *)bkt->blocks[15].data);
+ pk_mem_assert(&bkt->data[0] + 10 == bkt->blocks[15].data);
- fprintf(stdout, "blocks[0].size : %li\n", bkt->blocks[0].size);
- pk_mem_assert(54 == bkt->blocks[0].size);
+ fprintf(stdout, "blocks[15].size : %li\n", bkt->blocks[15].size);
+ pk_mem_assert(54 == bkt->blocks[15].size);
+
+ pk_bucket_destroy(bkt);
}
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_misalignment01);
pk_test_pkmem_teardown();
@@ -203,28 +229,31 @@ int main(int argc, char *argv[])
pk_test_pkmem_spinup();
fprintf(stdout, "[pkmem.cpp] start: %s\n", test_misalignment02);
{
- pk_membucket *bkt = pk_bucket_create("misalignment", 1024 * 1024, false);
+ pk_membucket *bkt = pk_bucket_create("misalignment", 1024 * 1024, PK_MEMBUCKET_FLAG_NONE);
+ pk_bucket_set_client_bucket(bkt);
pk_new(1, 1, bkt);
pk_new(1, 64, bkt);
pk_new(9, 16, bkt);
- fprintf(stdout, "lastEmptyBlockIndex: %li\n", bkt->lastEmptyBlockIndex);
- pk_mem_assert(2 == bkt->lastEmptyBlockIndex);
+ fprintf(stdout, "block_head_r: %u\n", bkt->block_head_r);
+ pk_mem_assert(2 == bkt->block_head_r);
- fprintf(stdout, "head : %li\n", bkt->head);
+ fprintf(stdout, "head : %li\n", bkt->head);
pk_mem_assert(65 == bkt->head);
- fprintf(stdout, "blocks[0].data : %p\n", (void *)bkt->blocks[0].data);
- pk_mem_assert(bkt->ptr + 1 == bkt->blocks[0].data);
+ fprintf(stdout, "blocks[15].data : %p\n", (void *)bkt->blocks[15].data);
+ pk_mem_assert(&bkt->data[0] + 1 == bkt->blocks[15].data);
- fprintf(stdout, "blocks[0].size : %li\n", bkt->blocks[0].size);
- pk_mem_assert(15 == bkt->blocks[0].size);
+ fprintf(stdout, "blocks[15].size : %li\n", bkt->blocks[15].size);
+ pk_mem_assert(15 == bkt->blocks[15].size);
- fprintf(stdout, "blocks[1].data : %p\n", (void *)bkt->blocks[1].data);
- pk_mem_assert(bkt->ptr + 25 == bkt->blocks[1].data);
+ fprintf(stdout, "blocks[14].data : %p\n", (void *)bkt->blocks[14].data);
+ pk_mem_assert(&bkt->data[0] + 25 == bkt->blocks[14].data);
- fprintf(stdout, "blocks[1].size : %li\n", bkt->blocks[1].size);
- pk_mem_assert(39 == bkt->blocks[1].size);
+ fprintf(stdout, "blocks[14].size : %li\n", bkt->blocks[14].size);
+ pk_mem_assert(39 == bkt->blocks[14].size);
+
+ pk_bucket_destroy(bkt);
}
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_misalignment02);
pk_test_pkmem_teardown();
@@ -236,20 +265,20 @@ int main(int argc, char *argv[])
FreeTest01 ft{};
ft.ensureState();
- fprintf(stdout, "blocks[0].data : %p\n", (void *)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);
- pk_mem_assert(6 == ft.bkt->blocks[0].size);
+ fprintf(stdout, "blocks[15].data : %p\n", (void *)ft.bkt->blocks[15].data);
+ pk_mem_assert(&ft.bkt->data[0] + 2 == ft.bkt->blocks[15].data);
+ fprintf(stdout, "blocks[15].size : %li\n", ft.bkt->blocks[15].size);
+ pk_mem_assert(6 == ft.bkt->blocks[15].size);
- fprintf(stdout, "blocks[1].data : %p\n", (void *)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);
- pk_mem_assert(4 == ft.bkt->blocks[1].size);
+ fprintf(stdout, "blocks[14].data : %p\n", (void *)ft.bkt->blocks[14].data);
+ pk_mem_assert(&ft.bkt->data[0] + 12 == ft.bkt->blocks[14].data);
+ fprintf(stdout, "blocks[14].size : %li\n", ft.bkt->blocks[14].size);
+ pk_mem_assert(4 == ft.bkt->blocks[14].size);
- fprintf(stdout, "blocks[2].data : %p\n", (void *)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);
- pk_mem_assert(32 == ft.bkt->blocks[2].size);
+ fprintf(stdout, "blocks[13].data : %p\n", (void *)ft.bkt->blocks[13].data);
+ pk_mem_assert(&ft.bkt->data[0] + 32 == ft.bkt->blocks[13].data);
+ fprintf(stdout, "blocks[13].size : %li\n", ft.bkt->blocks[13].size);
+ pk_mem_assert(32 == ft.bkt->blocks[13].size);
}
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_0000);
pk_test_pkmem_teardown();
@@ -268,25 +297,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);
- pk_mem_assert(3 == ft.bkt->lastEmptyBlockIndex);
- fprintf(stdout, "head : %li\n", ft.bkt->head);
+ fprintf(stdout, "block_head_r: %u\n", ft.bkt->block_head_r);
+ pk_mem_assert(3 == ft.bkt->block_head_r);
+ fprintf(stdout, "head : %li\n", ft.bkt->head);
pk_mem_assert(expected_head == ft.bkt->head);
- fprintf(stdout, "blocks[0].data : %p\n", (void *)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);
- pk_mem_assert(8 == ft.bkt->blocks[0].size);
+ fprintf(stdout, "blocks[15].data : %p\n", (void *)ft.bkt->blocks[15].data);
+ pk_mem_assert(&ft.bkt->data[0] + 0 == ft.bkt->blocks[15].data);
+ fprintf(stdout, "blocks[15].size : %li\n", ft.bkt->blocks[15].size);
+ pk_mem_assert(8 == ft.bkt->blocks[15].size);
- fprintf(stdout, "blocks[1].data : %p\n", (void *)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);
- pk_mem_assert(4 == ft.bkt->blocks[1].size);
+ fprintf(stdout, "blocks[14].data : %p\n", (void *)ft.bkt->blocks[14].data);
+ pk_mem_assert(&ft.bkt->data[0] + 12 == ft.bkt->blocks[14].data);
+ fprintf(stdout, "blocks[14].size : %li\n", ft.bkt->blocks[14].size);
+ pk_mem_assert(4 == ft.bkt->blocks[14].size);
- fprintf(stdout, "blocks[2].data : %p\n", (void *)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);
- pk_mem_assert(32 == ft.bkt->blocks[2].size);
+ fprintf(stdout, "blocks[13].data : %p\n", (void *)ft.bkt->blocks[13].data);
+ pk_mem_assert(&ft.bkt->data[0] + 32 == ft.bkt->blocks[13].data);
+ fprintf(stdout, "blocks[13].size : %li\n", ft.bkt->blocks[13].size);
+ pk_mem_assert(32 == ft.bkt->blocks[13].size);
}
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_1000);
pk_test_pkmem_teardown();
@@ -305,20 +334,20 @@ 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);
- pk_mem_assert(2 == ft.bkt->lastEmptyBlockIndex);
- fprintf(stdout, "head : %li\n", ft.bkt->head);
+ fprintf(stdout, "block_head_r: %u\n", ft.bkt->block_head_r);
+ pk_mem_assert(2 == ft.bkt->block_head_r);
+ fprintf(stdout, "head : %li\n", ft.bkt->head);
pk_mem_assert(expected_head == ft.bkt->head);
- fprintf(stdout, "blocks[0].data : %p\n", (void *)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);
- pk_mem_assert(6 == ft.bkt->blocks[0].size);
+ fprintf(stdout, "blocks[15].data : %p\n", (void *)ft.bkt->blocks[15].data);
+ pk_mem_assert(&ft.bkt->data[0] + 2 == ft.bkt->blocks[15].data);
+ fprintf(stdout, "blocks[15].size : %li\n", ft.bkt->blocks[15].size);
+ pk_mem_assert(6 == ft.bkt->blocks[15].size);
- fprintf(stdout, "blocks[1].data : %p\n", (void *)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);
- pk_mem_assert(4 == ft.bkt->blocks[1].size);
+ fprintf(stdout, "blocks[14].data : %p\n", (void *)ft.bkt->blocks[14].data);
+ pk_mem_assert(&ft.bkt->data[0] + 12 == ft.bkt->blocks[14].data);
+ fprintf(stdout, "blocks[14].size : %li\n", ft.bkt->blocks[14].size);
+ pk_mem_assert(4 == ft.bkt->blocks[14].size);
}
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_0100);
pk_test_pkmem_teardown();
@@ -338,20 +367,20 @@ 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);
- pk_mem_assert(2 == ft.bkt->lastEmptyBlockIndex);
- fprintf(stdout, "head : %li\n", ft.bkt->head);
+ fprintf(stdout, "block_head_r: %u\n", ft.bkt->block_head_r);
+ pk_mem_assert(2 == ft.bkt->block_head_r);
+ fprintf(stdout, "head : %li\n", ft.bkt->head);
pk_mem_assert(expected_head == ft.bkt->head);
- fprintf(stdout, "blocks[0].data : %p\n", (void *)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);
- pk_mem_assert(6 == ft.bkt->blocks[0].size);
+ fprintf(stdout, "blocks[15].data : %p\n", (void *)ft.bkt->blocks[15].data);
+ pk_mem_assert(&ft.bkt->data[0] + 2 == ft.bkt->blocks[15].data);
+ fprintf(stdout, "blocks[15].size : %li\n", ft.bkt->blocks[15].size);
+ pk_mem_assert(6 == ft.bkt->blocks[15].size);
- fprintf(stdout, "blocks[1].data : %p\n", (void *)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);
- pk_mem_assert(52 == ft.bkt->blocks[1].size);
+ fprintf(stdout, "blocks[14].data : %p\n", (void *)ft.bkt->blocks[14].data);
+ pk_mem_assert(&ft.bkt->data[0] + 12 == ft.bkt->blocks[14].data);
+ fprintf(stdout, "blocks[14].size : %li\n", ft.bkt->blocks[14].size);
+ pk_mem_assert(52 == ft.bkt->blocks[14].size);
}
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_0010);
pk_test_pkmem_teardown();
@@ -371,20 +400,20 @@ 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);
- pk_mem_assert(2 == ft.bkt->lastEmptyBlockIndex);
- fprintf(stdout, "head : %li\n", ft.bkt->head);
+ fprintf(stdout, "block_head_r: %u\n", ft.bkt->block_head_r);
+ pk_mem_assert(2 == ft.bkt->block_head_r);
+ fprintf(stdout, "head : %li\n", ft.bkt->head);
pk_mem_assert(expected_head == ft.bkt->head);
- fprintf(stdout, "blocks[0].data : %p\n", (void *)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);
- pk_mem_assert(14 == ft.bkt->blocks[0].size);
+ fprintf(stdout, "blocks[15].data : %p\n", (void *)ft.bkt->blocks[15].data);
+ pk_mem_assert(&ft.bkt->data[0] + 2 == ft.bkt->blocks[15].data);
+ fprintf(stdout, "blocks[15].size : %li\n", ft.bkt->blocks[15].size);
+ pk_mem_assert(14 == ft.bkt->blocks[15].size);
- fprintf(stdout, "blocks[1].data : %p\n", (void *)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);
- pk_mem_assert(32 == ft.bkt->blocks[1].size);
+ fprintf(stdout, "blocks[14].data : %p\n", (void *)ft.bkt->blocks[14].data);
+ pk_mem_assert(&ft.bkt->data[0] + 32 == ft.bkt->blocks[14].data);
+ fprintf(stdout, "blocks[14].size : %li\n", ft.bkt->blocks[14].size);
+ pk_mem_assert(32 == ft.bkt->blocks[14].size);
}
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_0001);
pk_test_pkmem_teardown();
@@ -400,20 +429,20 @@ int main(int argc, char *argv[])
// [00-31 memblock
pk_delete(ft.ptrs[0], ft.sz[0], ft.bkt);
- fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex);
- pk_mem_assert(2 == ft.bkt->lastEmptyBlockIndex);
- fprintf(stdout, "head : %li\n", ft.bkt->head);
+ fprintf(stdout, "block_head_r: %u\n", ft.bkt->block_head_r);
+ pk_mem_assert(2 == ft.bkt->block_head_r);
+ fprintf(stdout, "head : %li\n", ft.bkt->head);
pk_mem_assert(65 == ft.bkt->head);
- fprintf(stdout, "blocks[0].data : %p\n", (void *)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);
- pk_mem_assert(32 == ft.bkt->blocks[0].size);
+ fprintf(stdout, "blocks[15].data : %p\n", (void *)ft.bkt->blocks[15].data);
+ pk_mem_assert(&ft.bkt->data[0] + 0 == ft.bkt->blocks[15].data);
+ fprintf(stdout, "blocks[15].size : %li\n", ft.bkt->blocks[15].size);
+ pk_mem_assert(32 == ft.bkt->blocks[15].size);
- fprintf(stdout, "blocks[1].data : %p\n", (void *)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);
- pk_mem_assert(31 == ft.bkt->blocks[1].size);
+ fprintf(stdout, "blocks[14].data : %p\n", (void *)ft.bkt->blocks[14].data);
+ pk_mem_assert(&ft.bkt->data[0] + 33 == ft.bkt->blocks[14].data);
+ fprintf(stdout, "blocks[14].size : %li\n", ft.bkt->blocks[14].size);
+ pk_mem_assert(31 == ft.bkt->blocks[14].size);
}
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_after);
pk_test_pkmem_teardown();
@@ -438,23 +467,23 @@ int main(int argc, char *argv[])
void *ptr4 = pk_new(31, 1, ft.bkt);
void *ptr5 = pk_new( 1, 1, ft.bkt);
- fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex);
- pk_mem_assert(0 == ft.bkt->lastEmptyBlockIndex);
- fprintf(stdout, "head : %li\n", ft.bkt->head);
+ fprintf(stdout, "block_head_r: %u\n", ft.bkt->block_head_r);
+ pk_mem_assert(0 == ft.bkt->block_head_r);
+ fprintf(stdout, "head : %li\n", ft.bkt->head);
pk_mem_assert(66 == ft.bkt->head);
- fprintf(stdout, "ptr0 : %p\n", ft.ptrs[0]);
- pk_mem_assert(ft.bkt->ptr + 0 == ft.ptrs[0]);
- fprintf(stdout, "ptr3 : %p\n", ptr3);
- pk_mem_assert(ft.bkt->ptr + 19 == ptr3);
- fprintf(stdout, "ptr2 : %p\n", ft.ptrs[2]);
- pk_mem_assert(ft.bkt->ptr + 32 == ft.ptrs[2]);
- fprintf(stdout, "ptr4 : %p\n", ptr4);
- pk_mem_assert(ft.bkt->ptr + 33 == ptr4);
- fprintf(stdout, "ptr1 : %p\n", ft.ptrs[1]);
- pk_mem_assert(ft.bkt->ptr + 64 == ft.ptrs[1]);
- fprintf(stdout, "ptr5 : %p\n", ptr5);
- pk_mem_assert(ft.bkt->ptr + 65 == ptr5);
+ fprintf(stdout, "ptr0 : %p\n", ft.ptrs[0]);
+ pk_mem_assert(&ft.bkt->data[0] + 0 == ft.ptrs[0]);
+ fprintf(stdout, "ptr3 : %p\n", ptr3);
+ pk_mem_assert(&ft.bkt->data[0] + 19 == ptr3);
+ fprintf(stdout, "ptr2 : %p\n", ft.ptrs[2]);
+ pk_mem_assert(&ft.bkt->data[0] + 32 == ft.ptrs[2]);
+ fprintf(stdout, "ptr4 : %p\n", ptr4);
+ pk_mem_assert(&ft.bkt->data[0] + 33 == ptr4);
+ fprintf(stdout, "ptr1 : %p\n", ft.ptrs[1]);
+ pk_mem_assert(&ft.bkt->data[0] + 64 == ft.ptrs[1]);
+ fprintf(stdout, "ptr5 : %p\n", ptr5);
+ pk_mem_assert(&ft.bkt->data[0] + 65 == ptr5);
/* free [19-31]
[00-18] (19) ptr0
@@ -468,28 +497,28 @@ int main(int argc, char *argv[])
pk_delete(ptr3, 13, ft.bkt);
ptr3 = nullptr;
- fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex);
- pk_mem_assert(1 == ft.bkt->lastEmptyBlockIndex);
- fprintf(stdout, "head : %li\n", ft.bkt->head);
+ fprintf(stdout, "block_head_r: %u\n", ft.bkt->block_head_r);
+ pk_mem_assert(1 == ft.bkt->block_head_r);
+ fprintf(stdout, "head : %li\n", ft.bkt->head);
pk_mem_assert(66 == ft.bkt->head);
- fprintf(stdout, "ptr0 : %p\n", ft.ptrs[0]);
- pk_mem_assert(ft.bkt->ptr + 0 == ft.ptrs[0]);
- fprintf(stdout, "ptr3 : %p\n", ptr3);
+ fprintf(stdout, "ptr0 : %p\n", ft.ptrs[0]);
+ pk_mem_assert(&ft.bkt->data[0] + 0 == ft.ptrs[0]);
+ fprintf(stdout, "ptr3 : %p\n", ptr3);
pk_mem_assert(nullptr == ptr3);
- fprintf(stdout, "ptr2 : %p\n", ft.ptrs[2]);
- pk_mem_assert(ft.bkt->ptr + 32 == ft.ptrs[2]);
- fprintf(stdout, "ptr4 : %p\n", ptr4);
- pk_mem_assert(ft.bkt->ptr + 33 == ptr4);
- fprintf(stdout, "ptr1 : %p\n", ft.ptrs[1]);
- pk_mem_assert(ft.bkt->ptr + 64 == ft.ptrs[1]);
- fprintf(stdout, "ptr5 : %p\n", ptr5);
- pk_mem_assert(ft.bkt->ptr + 65 == ptr5);
-
- fprintf(stdout, "blocks[0].data : %p\n", (void *)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);
- pk_mem_assert(13 == ft.bkt->blocks[0].size);
+ fprintf(stdout, "ptr2 : %p\n", ft.ptrs[2]);
+ pk_mem_assert(&ft.bkt->data[0] + 32 == ft.ptrs[2]);
+ fprintf(stdout, "ptr4 : %p\n", ptr4);
+ pk_mem_assert(&ft.bkt->data[0] + 33 == ptr4);
+ fprintf(stdout, "ptr1 : %p\n", ft.ptrs[1]);
+ pk_mem_assert(&ft.bkt->data[0] + 64 == ft.ptrs[1]);
+ fprintf(stdout, "ptr5 : %p\n", ptr5);
+ pk_mem_assert(&ft.bkt->data[0] + 65 == ptr5);
+
+ fprintf(stdout, "blocks[15].data : %p\n", (void *)ft.bkt->blocks[15].data);
+ pk_mem_assert(&ft.bkt->data[0] + 19 == ft.bkt->blocks[15].data);
+ fprintf(stdout, "blocks[15].size : %li\n", ft.bkt->blocks[15].size);
+ pk_mem_assert(13 == ft.bkt->blocks[15].size);
/* free [32] which gets absorbed into 19-32
[19-32] (13) memblock
@@ -498,28 +527,28 @@ int main(int argc, char *argv[])
pk_delete(ft.ptrs[2], ft.sz[2], ft.bkt);
ft.ptrs[2] = nullptr;
- fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex);
- pk_mem_assert(1 == ft.bkt->lastEmptyBlockIndex);
- fprintf(stdout, "head : %li\n", ft.bkt->head);
+ fprintf(stdout, "block_head_r: %u\n", ft.bkt->block_head_r);
+ pk_mem_assert(1 == ft.bkt->block_head_r);
+ fprintf(stdout, "head : %li\n", ft.bkt->head);
pk_mem_assert(66 == ft.bkt->head);
- fprintf(stdout, "ptr0 : %p\n", ft.ptrs[0]);
- pk_mem_assert(ft.bkt->ptr + 0 == ft.ptrs[0]);
- fprintf(stdout, "ptr3 : %p\n", ptr3);
+ fprintf(stdout, "ptr0 : %p\n", ft.ptrs[0]);
+ pk_mem_assert(&ft.bkt->data[0] + 0 == ft.ptrs[0]);
+ fprintf(stdout, "ptr3 : %p\n", ptr3);
pk_mem_assert(nullptr == ptr3);
- fprintf(stdout, "ptr2 : %p\n", ft.ptrs[2]);
+ fprintf(stdout, "ptr2 : %p\n", ft.ptrs[2]);
pk_mem_assert(nullptr == ft.ptrs[2]);
- fprintf(stdout, "ptr4 : %p\n", ptr4);
- pk_mem_assert(ft.bkt->ptr + 33 == ptr4);
- fprintf(stdout, "ptr1 : %p\n", ft.ptrs[1]);
- pk_mem_assert(ft.bkt->ptr + 64 == ft.ptrs[1]);
- fprintf(stdout, "ptr5 : %p\n", ptr5);
- pk_mem_assert(ft.bkt->ptr + 65 == ptr5);
-
- fprintf(stdout, "blocks[0].data : %p\n", (void *)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);
- pk_mem_assert(14 == ft.bkt->blocks[0].size);
+ fprintf(stdout, "ptr4 : %p\n", ptr4);
+ pk_mem_assert(&ft.bkt->data[0] + 33 == ptr4);
+ fprintf(stdout, "ptr1 : %p\n", ft.ptrs[1]);
+ pk_mem_assert(&ft.bkt->data[0] + 64 == ft.ptrs[1]);
+ fprintf(stdout, "ptr5 : %p\n", ptr5);
+ pk_mem_assert(&ft.bkt->data[0] + 65 == ptr5);
+
+ fprintf(stdout, "blocks[15].data : %p\n", (void *)ft.bkt->blocks[15].data);
+ pk_mem_assert(&ft.bkt->data[0] + 19 == ft.bkt->blocks[15].data);
+ fprintf(stdout, "blocks[15].size : %li\n", ft.bkt->blocks[15].size);
+ pk_mem_assert(14 == ft.bkt->blocks[15].size);
}
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_before);
pk_test_pkmem_teardown();
@@ -536,22 +565,22 @@ int main(int argc, char *argv[])
pk_delete(ft.ptrs[2], ft.sz[2], ft.bkt);
ft.ptrs[2] = nullptr;
- fprintf(stdout, "lastEmptyBlockIndex: %li\n", ft.bkt->lastEmptyBlockIndex);
- pk_mem_assert(1 == ft.bkt->lastEmptyBlockIndex);
- fprintf(stdout, "head : %li\n", ft.bkt->head);
+ fprintf(stdout, "block_head_r: %u\n", ft.bkt->block_head_r);
+ pk_mem_assert(1 == ft.bkt->block_head_r);
+ fprintf(stdout, "head : %li\n", ft.bkt->head);
pk_mem_assert(65 == ft.bkt->head);
- fprintf(stdout, "ptr0 : %p\n", ft.ptrs[0]);
- pk_mem_assert(ft.bkt->ptr + 0 == ft.ptrs[0]);
- fprintf(stdout, "ptr2 : %p\n", ft.ptrs[2]);
+ fprintf(stdout, "ptr0 : %p\n", ft.ptrs[0]);
+ pk_mem_assert(&ft.bkt->data[0] + 0 == ft.ptrs[0]);
+ fprintf(stdout, "ptr2 : %p\n", ft.ptrs[2]);
pk_mem_assert(nullptr == ft.ptrs[2]);
- fprintf(stdout, "ptr1 : %p\n", ft.ptrs[1]);
- pk_mem_assert(ft.bkt->ptr + 64 == ft.ptrs[1]);
+ fprintf(stdout, "ptr1 : %p\n", ft.ptrs[1]);
+ pk_mem_assert(&ft.bkt->data[0] + 64 == ft.ptrs[1]);
- fprintf(stdout, "blocks[0].data : %p\n", (void *)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);
- pk_mem_assert(45 == ft.bkt->blocks[0].size);
+ fprintf(stdout, "blocks[15].data : %p\n", (void *)ft.bkt->blocks[15].data);
+ pk_mem_assert(&ft.bkt->data[0] + 19 == ft.bkt->blocks[15].data);
+ fprintf(stdout, "blocks[15].size : %li\n", ft.bkt->blocks[15].size);
+ pk_mem_assert(45 == ft.bkt->blocks[15].size);
}
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_free_between);
pk_test_pkmem_teardown();
@@ -560,37 +589,37 @@ int main(int argc, char *argv[])
fprintf(stdout, "[pkmem.cpp] start: %s\n", test_alloc_strings);
{
size_t diff;
- pk_membucket *bkt = pk_bucket_create(test_free_between, PK_DEFAULT_BUCKET_SIZE, false);
+ pk_membucket *bkt = pk_bucket_create(test_free_between, PK_DEFAULT_BUCKET_SIZE, PK_MEMBUCKET_FLAG_NONE);
char *str1 = pk_new<char>(16, bkt);
char *str2 = pk_new<char>(16, bkt);
pk_handle *handle1 = pk_new<pk_handle>(bkt);
pk_handle *handle2 = pk_new<pk_handle>(bkt);
- fprintf(stdout, "ptr : %p\n", (void *)bkt->ptr);
- fprintf(stdout, "str1 : %p\n", (void *)str1);
- fprintf(stdout, "str2 : %p\n", (void *)str2);
- fprintf(stdout, "handle1 : %p\n", (void *)handle1);
- fprintf(stdout, "handle2 : %p\n", (void *)handle2);
+ fprintf(stdout, "ptr : %p\n", (void *)&bkt->data[0]);
+ fprintf(stdout, "str1 : %p\n", (void *)str1);
+ fprintf(stdout, "str2 : %p\n", (void *)str2);
+ fprintf(stdout, "handle1 : %p\n", (void *)handle1);
+ fprintf(stdout, "handle2 : %p\n", (void *)handle2);
- diff = str1 - bkt->ptr;
- fprintf(stdout, "str1 - ptr : %zu\n", diff);
+ diff = str1 - &bkt->data[0];
+ fprintf(stdout, "str1 - ptr : %zu\n", diff);
pk_mem_assert(diff == 0);
diff = str2 - str1;
- fprintf(stdout, "str2 - str1 : %zu\n", diff);
+ fprintf(stdout, "str2 - str1 : %zu\n", diff);
pk_mem_assert(diff == 16);
- diff = str2 - bkt->ptr;
- fprintf(stdout, "str2 - ptr : %zu\n", diff);
+ diff = str2 - &bkt->data[0];
+ fprintf(stdout, "str2 - ptr : %zu\n", diff);
pk_mem_assert(diff == 16);
diff = (char *)handle1 - str1;
- fprintf(stdout, "handle1 - str1 : %zu\n", diff);
+ fprintf(stdout, "handle1 - str1 : %zu\n", diff);
pk_mem_assert(diff == 32);
diff = (char *)handle2 - (char *)handle1;
- fprintf(stdout, "handle2 - handle1 : %zu\n", diff);
+ fprintf(stdout, "handle2 - handle1 : %zu\n", diff);
pk_mem_assert(diff == 8);
pk_bucket_destroy(bkt);
@@ -599,29 +628,32 @@ int main(int argc, char *argv[])
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);
+ pk_membucket *bkt = pk_bucket_create("lol", 1024, PK_MEMBUCKET_FLAG_NONE);
pk_mem_assert(bkt != nullptr);
(void)bkt;
}
- pk_membucket *bkt = pk_bucket_create("lol", 1024, false);
+ pk_membucket *bkt = pk_bucket_create("lol", 1024, PK_MEMBUCKET_FLAG_NONE);
pk_mem_assert(bkt == nullptr);
}
while(false);
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_bucket_count01);
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);
+ pk_membucket *bkt = pk_bucket_create("lol2", 1024, PK_MEMBUCKET_FLAG_NONE);
char *asdf = pk_new<char>(768, bkt);
pk_mem_assert(asdf != nullptr);
}
@@ -631,15 +663,17 @@ int main(int argc, char *argv[])
while(false);
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_bucket_count02);
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
{
pk_membucket *bkt = nullptr;
for (i = 0; i < PK_MAX_BUCKET_COUNT; ++i) {
- bkt = pk_bucket_create("lol3", 1024, false);
+ bkt = pk_bucket_create("lol3", 1024, PK_MEMBUCKET_FLAG_NONE);
char *asdf = pk_new<char>(768, bkt);
pk_mem_assert(asdf != nullptr);
}
@@ -649,76 +683,79 @@ int main(int argc, char *argv[])
while(false);
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_bucket_count03);
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);
- pk_membucket *bkt2 = pk_bucket_create("bucket2", 1024, false);
- pk_membucket *bkt3 = pk_bucket_create("bucket3", 1024, false);
- pk_membucket *bkt4 = pk_bucket_create("bucket4", 1024, false);
+ pk_membucket *bkt1 = pk_bucket_create("bucket1", 1024, PK_MEMBUCKET_FLAG_NONE);
+ pk_membucket *bkt2 = pk_bucket_create("bucket2", 1024, PK_MEMBUCKET_FLAG_NONE);
+ pk_membucket *bkt3 = pk_bucket_create("bucket3", 1024, PK_MEMBUCKET_FLAG_NONE);
+ pk_membucket *bkt4 = pk_bucket_create("bucket4", 1024, PK_MEMBUCKET_FLAG_NONE);
- fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head);
- pk_mem_assert(4 == pk_bucket_head);
+ fprintf(stdout, "debug_alloc_head: %li\n", debug_alloc_head);
+ pk_mem_assert(4 == debug_alloc_head);
pk_bucket_destroy(bkt4);
- fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head);
- pk_mem_assert(3 == pk_bucket_head);
+ fprintf(stdout, "debug_alloc_head: %li\n", debug_alloc_head);
+ pk_mem_assert(3 == debug_alloc_head);
pk_bucket_destroy(bkt3);
- fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head);
- pk_mem_assert(2 == pk_bucket_head);
+ fprintf(stdout, "debug_alloc_head: %li\n", debug_alloc_head);
+ pk_mem_assert(2 == debug_alloc_head);
pk_bucket_destroy(bkt2);
- fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head);
- pk_mem_assert(1 == pk_bucket_head);
+ fprintf(stdout, "debug_alloc_head: %li\n", debug_alloc_head);
+ pk_mem_assert(1 == debug_alloc_head);
pk_bucket_destroy(bkt1);
- fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head);
- pk_mem_assert(0 == pk_bucket_head);
+ fprintf(stdout, "debug_alloc_head: %li\n", debug_alloc_head);
+ pk_mem_assert(0 == debug_alloc_head);
}
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_bucket_count04);
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
+ * debug_alloc_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);
- pk_membucket *bkt2 = pk_bucket_create("bucket2", 1024, false);
- pk_membucket *bkt3 = pk_bucket_create("bucket3", 1024, false);
- pk_membucket *bkt4 = pk_bucket_create("bucket4", 1024, false);
+ pk_membucket *bkt1 = pk_bucket_create("bucket1", 1024, PK_MEMBUCKET_FLAG_NONE);
+ pk_membucket *bkt2 = pk_bucket_create("bucket2", 1024, PK_MEMBUCKET_FLAG_NONE);
+ pk_membucket *bkt3 = pk_bucket_create("bucket3", 1024, PK_MEMBUCKET_FLAG_NONE);
+ pk_membucket *bkt4 = pk_bucket_create("bucket4", 1024, PK_MEMBUCKET_FLAG_NONE);
- fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head);
- pk_mem_assert(4 == pk_bucket_head);
+ fprintf(stdout, "debug_alloc_head: %li\n", debug_alloc_head);
+ pk_mem_assert(4 == debug_alloc_head);
pk_bucket_destroy(bkt1);
- fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head);
- pk_mem_assert(4 == pk_bucket_head);
+ fprintf(stdout, "debug_alloc_head: %li\n", debug_alloc_head);
+ pk_mem_assert(4 == debug_alloc_head);
pk_bucket_destroy(bkt2);
- fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head);
- pk_mem_assert(4 == pk_bucket_head);
+ fprintf(stdout, "debug_alloc_head: %li\n", debug_alloc_head);
+ pk_mem_assert(4 == debug_alloc_head);
pk_bucket_destroy(bkt3);
- fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head);
- pk_mem_assert(4 == pk_bucket_head);
+ fprintf(stdout, "debug_alloc_head: %li\n", debug_alloc_head);
+ pk_mem_assert(4 == debug_alloc_head);
pk_bucket_destroy(bkt4);
- fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head);
- pk_mem_assert(3 == pk_bucket_head);
+ fprintf(stdout, "debug_alloc_head: %li\n", debug_alloc_head);
+ pk_mem_assert(0 == debug_alloc_head);
+ /*
pk_memory_flush();
- fprintf(stdout, "pk_bucket_head: %li\n", pk_bucket_head);
- pk_mem_assert(0 == pk_bucket_head);
+ fprintf(stdout, "debug_alloc_head: %li\n", debug_alloc_head);
+ pk_mem_assert(0 == debug_alloc_head);
+ */
}
fprintf(stdout, "[pkmem.cpp] end: %s\n\n", test_bucket_count05);
pk_test_pkmem_teardown();