about summary refs log tree commit diff stats
path: root/src/salloc.c
diff options
context:
space:
mode:
authorRen Kararou <[email protected]>2025-01-30 06:12:18 -0600
committerRen Kararou <[email protected]>2025-01-30 06:12:18 -0600
commit1e468866fc4455193df8d33b1711b6519dd4c721 (patch)
tree4c8478fabe1b5b189e443efe0332cdb2319bc07e /src/salloc.c
downloadlibspicy-1e468866fc4455193df8d33b1711b6519dd4c721.tar.gz
libspicy-1e468866fc4455193df8d33b1711b6519dd4c721.tar.bz2
libspicy-1e468866fc4455193df8d33b1711b6519dd4c721.zip
spicy allocator get!
Diffstat (limited to 'src/salloc.c')
-rw-r--r--src/salloc.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/salloc.c b/src/salloc.c
new file mode 100644
index 0000000..6c20b41
--- /dev/null
+++ b/src/salloc.c
@@ -0,0 +1,115 @@
+#include "salloc.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+struct spicy_allocation {
+	size_t pagenum;
+	size_t size;
+	size_t *start;
+	size_t *prev;
+};
+
+struct spicy_page {
+	size_t *start;
+	size_t *current;
+	size_t free;
+};
+
+static struct {
+	size_t pagecount;
+	size_t pagesize;
+	size_t *c;
+	size_t max_pages;
+	size_t max_allocs;
+	size_t csize;
+	struct spicy_page *pages;
+	struct spicy_allocation *allocs;
+} spicy_arena = {
+	.pagecount = 0,
+	.pagesize = 10240,
+	.c = NULL,
+	.max_pages = 1024,
+	.max_allocs = 10240,
+	.csize = (1024 * sizeof(struct spicy_page)) + (1024 * sizeof(struct spicy_allocation)),
+	.pages = NULL,
+	.allocs = NULL
+};
+
+int salloc_configure(size_t pagesize, size_t max_pages, size_t max_allocs) {
+	if (spicy_arena.c != NULL) return -1; // allocator already used!
+	spicy_arena.pagesize = pagesize;
+	spicy_arena.max_pages = max_pages;
+	spicy_arena.max_allocs = max_allocs;
+	spicy_arena.csize = max_pages + max_allocs;
+	return 0;
+}
+
+void *salloc(size_t size) {
+	if (spicy_arena.c == NULL) {
+		spicy_arena.c = malloc(spicy_arena.csize);
+		if (spicy_arena.c == NULL) return NULL;
+	}
+	if (spicy_arena.pages == NULL) {
+		spicy_arena.pages = (struct spicy_page *)spicy_arena.c;
+	}
+	if (spicy_arena.allocs == NULL) {
+		spicy_arena.allocs = (struct spicy_allocation *)(spicy_arena.c + (spicy_arena.max_pages * sizeof(struct spicy_page)));
+	}
+	if (spicy_arena.pagecount == 0) {
+		spicy_arena.pages[0].start = malloc(spicy_arena.pagesize);
+		if (spicy_arena.pages[0].start == NULL) return NULL;
+		spicy_arena.pages[0].current = spicy_arena.pages[0].start;
+		spicy_arena.pages[0].free = spicy_arena.pagesize;
+		spicy_arena.pagecount++;
+	}
+	// This is inefficient!
+	for (size_t i = 0; i < spicy_arena.max_allocs; i++) {
+		if (spicy_arena.allocs[i].start == NULL) {
+			if (spicy_arena.allocs[i].size >= size) {
+				spicy_arena.allocs[i].start = spicy_arena.allocs[i].prev;
+				return (void *)spicy_arena.allocs[i].start;
+			}
+			if (spicy_arena.allocs[i].size == 0) {
+				for (size_t x = 0; x < spicy_arena.pagecount; x++) {
+					if (spicy_arena.pages[x].free >= size) {
+						void *ret = spicy_arena.pages[x].current;
+						spicy_arena.pages[x].current += size;
+						spicy_arena.pages[x].free -= size;
+						return ret;
+					}
+				}
+			spicy_arena.pages[spicy_arena.pagecount].start = malloc(spicy_arena.pagesize);
+			if (spicy_arena.pages[spicy_arena.pagecount].start == NULL) return NULL;
+			void *ret = spicy_arena.pages[spicy_arena.pagecount].start;
+			spicy_arena.pages[spicy_arena.pagecount].current = spicy_arena.pages[spicy_arena.pagecount].start + size;
+			spicy_arena.pages[spicy_arena.pagecount].free = spicy_arena.pagesize - size;
+			spicy_arena.pagecount++;
+			return ret;
+			}
+		}
+	}
+	return NULL;
+}
+
+void *scalloc(size_t count, size_t size) {
+	void *ret = salloc(count * size);
+	if (ret != NULL) {
+		memset(ret, 0, count * size);
+		return ret;
+	}
+	return NULL;
+}
+
+void sfree(void *ptr) {
+	if (ptr == NULL) return;
+	for (size_t i = 0; i < spicy_arena.max_allocs; i++) {
+		if (ptr == spicy_arena.allocs[i].start) {
+			spicy_arena.allocs[i].prev = spicy_arena.allocs[i].start;
+			spicy_arena.allocs[i].start = NULL;
+			ptr = NULL;
+		}
+	}
+}
+