summaryrefslogtreecommitdiff
path: root/src/memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory.cpp')
-rw-r--r--src/memory.cpp92
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--;
+ }
+}