about summary refs log tree commit diff stats
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
downloadlibspicy-1e468866fc4455193df8d33b1711b6519dd4c721.tar.gz
libspicy-1e468866fc4455193df8d33b1711b6519dd4c721.tar.bz2
libspicy-1e468866fc4455193df8d33b1711b6519dd4c721.zip
spicy allocator get!
-rw-r--r--.clang-format92
-rw-r--r--.editorconfig19
-rw-r--r--.gitignore13
-rw-r--r--inc/salloc.h12
-rw-r--r--makefile53
-rw-r--r--src/salloc.c115
6 files changed, 304 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..7b092c2
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,92 @@
+---
+AccessModifierOffset: -4
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignOperands: true
+AlignTrailingComments: false
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: Empty
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortEnumsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Empty
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLambdasOnASingleLine: Empty
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+  AfterClass: false
+  AfterControlStatement: false
+  AfterEnum: false
+  AfterFunction: false
+  AfterNamespace: false
+  AfterObjCDeclaration: false
+  AfterStruct: false
+  AfterUnion: false
+  BeforeCatch: false
+  BeforeElse: false
+  IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: false
+BreakConstructorInitializersBeforeComma: false
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: false
+ColumnLimit: 80
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: false
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+IncludeCategories:
+  - Regex: '.*'
+    Priority: 1
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: false
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: Inner
+ObjCBlockIndentWidth: 4
+ObjCSpaceAfterProperty: true
+ObjCSpaceBeforeProtocolList: true
+
+# Taken from git's rules
+PenaltyBreakBeforeFirstCallParameter: 30
+PenaltyBreakComment: 10
+PenaltyBreakFirstLessLess: 0
+PenaltyBreakString: 10
+PenaltyExcessCharacter: 100
+PenaltyReturnTypeOnItsOwnLine: 60
+
+PointerAlignment: Left
+ReflowComments: false
+SortIncludes: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: false
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Latest
+TabWidth: 4
+UseTab: Never
+InsertBraces: true
+...
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..38ed40f
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,19 @@
+# .editorconfig
+
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+# makefile
+[makefile]
+indent_style = tab
+indent_size = 4
+
+# c source files
+[{*.c,*.h}]
+indent_style = tab
+indent_size = 4
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..de9f715
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+# editor ignores
+*~
+*.swp
+*.swo
+\#*\#
+.\#*
+
+# artefacts
+*.o
+*.so
+*.pch
+build/
+obj/
diff --git a/inc/salloc.h b/inc/salloc.h
new file mode 100644
index 0000000..d9d85da
--- /dev/null
+++ b/inc/salloc.h
@@ -0,0 +1,12 @@
+#ifndef LIBSPICY_SALLOC_H
+#define LIBSPICY_SALLOC_H
+
+#include <stdlib.h>
+
+int salloc_configure(size_t pagesize, size_t max_pages, size_t max_allocs);
+void *salloc(size_t size);
+void *scalloc(size_t number, size_t count);
+void sfree(void *ptr);
+
+#endif
+
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..26595fd
--- /dev/null
+++ b/makefile
@@ -0,0 +1,53 @@
+CC:=clang
+AR:=llvm-ar
+CFLAGS:=-march=native -O3 -funroll-loops -Wall -Wextra -Werror -fPIC
+LDFLAGS:=-flto=thin -lpthread
+
+ifeq ($(shell uname),SunOS)
+CC = gcc
+LDFLAGS += -lsocket
+CFLAGS += -std=gnu11
+else
+CFLAGS += -std=c11
+endif
+
+INCLUDES=-Iinc/
+
+OBJECTS=obj/salloc.o
+
+.PHONY: all
+all: build/lib/libspicy.so build/lib/static/libspicy.a includes
+
+.PHONY: includes
+includes:
+	@if [ ! -d "build/include/libspicy" ]; then mkdir -p build/include/libspicy; fi
+	@cp -v inc/*.h build/include/libspicy/
+
+.PHONY: release
+release: all build/rel/libspicy.so build/dbg/libspicy.so.debug
+
+build/rel/%: build/lib/%
+	@if [ ! -d "build/rel" ]; then mkdir -p build/rel; fi
+	strip -s -o $@ $<
+
+build/dbg/%.debug: build/lib/%
+	@if [ ! -d "build/dbg" ]; then mkdir -p build/dbg; fi
+	strip --only-keep-debug -o $@ $<
+
+build/lib/%.so: $(OBJECTS)
+	@if [ ! -d "build/lib" ]; then mkdir -p build/lib; fi
+	$(CC) -g -shared $(CFLAGS) $(LDFLAGS) -o $@ $^
+
+build/lib/static/%.a: $(OBJECTS)
+	@if [ ! -d "build/lib/static" ]; then mkdir -p build/lib/static; fi
+	$(AR) rcs $@ $^
+
+obj/%.o: src/%.c inc/%.h
+	@if [ ! -d "obj" ]; then mkdir -p obj; fi
+	$(CC) -g -c $(INCLUDES) $(CFLAGS) -o $@ $<
+
+.PHONY: clean
+clean:
+	@rm -rf obj
+	@rm -rf build
+
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;
+		}
+	}
+}
+