diff options
Diffstat (limited to 'src/memory.cpp')
| -rw-r--r-- | src/memory.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/memory.cpp b/src/memory.cpp new file mode 100644 index 0000000..83f8483 --- /dev/null +++ b/src/memory.cpp @@ -0,0 +1,92 @@ + +#include "memory.hpp" + +struct pke::MemBucket { + int64_t size; + int64_t head; + int64_t free; + int64_t allocs; + char * ptr; +}; + +pke::MemBucket buckets[128]; // 32 gigs +int64_t bucketHead = 0; + +int64_t InitNewBucket(int64_t sz) { + buckets[bucketHead].size = sz; + buckets[bucketHead].ptr = reinterpret_cast<char *>(std::malloc(sz)); + buckets[bucketHead].free = 0; + buckets[bucketHead].head = 0; + buckets[bucketHead].allocs = 0; + return bucketHead++; +} + +void *pke::PkeNew(std::size_t sz) { + MemBucket *bkt = nullptr; + for (long i = 0; i < bucketHead; ++i) { + if (buckets[i].size - buckets[i].head > sz) { + bkt = &buckets[i]; + } + } + if (bkt == nullptr) { + bkt = &buckets[InitNewBucket(DEFAULT_BUCKET_SIZE)]; + } + void *ptr = bkt->ptr + bkt->head; + bkt->head += sz; + bkt->allocs++; + return ptr; +} + +void *pke::PkeNew(std::size_t sz, pke::MemBucket *bkt) { + void *ptr = bkt->ptr + bkt->head; + bkt->head += sz; + bkt->allocs++; + return ptr; +} + +void pke::PkeDelete(void *ptr) { + pke::MemBucket *bkt = nullptr; + for (long i = 0; i < bucketHead; ++i) { + bkt = &buckets[i]; + if (ptr > bkt->ptr && ptr < bkt->ptr + bkt->size) break; + } + if (bkt == nullptr) { + std::printf("bad pointer %llu", reinterpret_cast<unsigned long long>(ptr)); + throw "bad pointer"; + } + bkt->allocs--; + if (bkt->allocs == 0) { + bkt->head = 0; + bkt->free = 0; + } +} + +void pke::PkeDelete(void *ptr, pke::MemBucket *bkt) { + bkt->allocs--; + if (bkt->allocs == 0) { + bkt->head = 0; + bkt->free = 0; + } +} + +pke::MemBucket *pke::BeginTransientBucket(int64_t sz) { + return &buckets[InitNewBucket(sz)]; +} + +void pke::EndTransientBucket(pke::MemBucket *bkt) { + int64_t foundIndex = -1; + for (int64_t i = 0; i < bucketHead; ++i) { + if (&buckets[i] == bkt) { + foundIndex = i; + std::free(bkt->ptr); + bkt->size = 0; + bkt->head = 0; + bkt->free = 0; + bkt->ptr = reinterpret_cast<char *>(0xCAFEBABE); + break; + } + } + if (foundIndex == bucketHead) { + bucketHead--; + } +} |
