added pool allocator to core library
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 14 Jan 2021 18:41:52 +0000 (12:41 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 14 Jan 2021 18:42:12 +0000 (12:42 -0600)
bin/onyx
core/alloc.onyx
core/alloc/pool.onyx [new file with mode: 0644]
core/stdio.onyx
onyx.exe
src/onyxutils.c

index 4ceb49909ab66bc12981f75bb464912393de23a1..6bc20b20a56b4be667b315a74d4ae7ae20489c41 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index 792e497c41c81b09c151b43a27000ca69cb13d55..9950f9a4c91d5176e78108036a8a996baf056fd4 100644 (file)
@@ -4,6 +4,7 @@ package core.alloc
 #load "core/alloc/fixed"
 #load "core/alloc/heap"
 #load "core/alloc/ring"
+#load "core/alloc/pool"
 
 TEMPORARY_ALLOCATOR_SIZE :: 1 << 12; // 4Kb
 
diff --git a/core/alloc/pool.onyx b/core/alloc/pool.onyx
new file mode 100644 (file)
index 0000000..4abf6a5
--- /dev/null
@@ -0,0 +1,66 @@
+package core.alloc.pool
+
+PoolAllocator :: struct (Elem: type_expr) {
+    buffer     : [] Elem;
+    first_free : ^Elem;
+}
+
+#private_file
+pool_allocator_proc :: proc (pool: ^PoolAllocator($Elem), aa: AllocationAction, size: u32, align: u32, oldptr: rawptr) -> rawptr {
+    switch aa {
+        case AllocationAction.Alloc {
+            assert(size == sizeof Elem, "Allocating wrong size from pool allocator.");
+            return pool_alloc(pool);
+        }
+
+        case AllocationAction.Resize {
+            assert(false, "Cannot resize in a pool allocator!");
+            return null;
+        }
+
+        case AllocationAction.Free {
+            pool_free(pool, ~~ oldptr);
+            return null;
+        }
+    }
+
+    return null;
+}
+
+pool_alloc :: proc (pool: ^PoolAllocator($Elem)) -> ^Elem {
+    if pool.first_free == null do return null;
+
+    defer pool.first_free = cast(^Elem) *(cast(^rawptr) pool.first_free);
+    return pool.first_free;
+}
+
+pool_free :: proc (pool: ^PoolAllocator($Elem), elem: ^Elem) {
+    // TODO: Maybe add a check that the elem pointer is actually in the buffer?? 
+    *(cast(^rawptr) elem) = cast(rawptr) pool.first_free;
+    pool.first_free = elem;
+}
+
+
+// This could become: proc (buffer: [] u8, $Elem: type_expr) -> PoolAllocator(Elem)
+// when that feature is implemented.
+make :: proc (buffer: [] $Elem) -> PoolAllocator(Elem) {
+    assert(sizeof Elem >= sizeof rawptr, "Cannot have a pool allocator of a type less than a rawptr in size.");
+
+    for i: 0 .. buffer.count - 1 {
+        *(cast(^rawptr) ^buffer[i]) = cast(rawptr) ^buffer[i + 1];
+    }
+
+    *(cast(^rawptr) ^buffer[buffer.count - 1]) = null;
+
+    return <PoolAllocator(Elem)>.{
+        buffer     = buffer,
+        first_free = ^buffer[0],
+    };
+}
+
+make_allocator :: proc (pool: ^PoolAllocator($Elem)) -> Allocator {
+    return Allocator.{
+        func = #solidify pool_allocator_proc { Elem = Elem },
+        data = pool,
+    };
+}
\ No newline at end of file
index c3e67fda749518e5b9f8516770ea8731821eb8a9..c0a235e77ad71b8de94e2b5a770f286418a3766b 100644 (file)
@@ -40,13 +40,24 @@ printf :: proc (format: str, va: ...) {
 }
 
 // This works on both slices and arrays
-print_array :: proc (arr: $T, sep := " ") {
-    for i: 0 .. arr.count {
-        print(arr.data[i]);
-        if i != arr.count - 1 do print(sep);
-    }
+print_array :: proc {
+    proc (arr: [$N] $T, sep := " ") {
+        for i: 0 .. N {
+            print(arr[i]);
+            if i != N - 1 do print(sep);
+        }
 
-    print("\n");
+        print("\n");
+    },
+
+    proc (arr: $T, sep := " ") {
+        for i: 0 .. arr.count {
+            print(arr.data[i]);
+            if i != arr.count - 1 do print(sep);
+        }
+
+        print("\n");
+    }
 }
 
 print_stream_flush :: proc () {
index b8a51481b2898517ce1baf85e77cbe6e4d9669d7..b54fafb6e2d360fc095c72147792273feedb255f 100644 (file)
Binary files a/onyx.exe and b/onyx.exe differ
index cfdd13e599a150d782a9695dc7648ca3c16172ad..0fd12a0848dd17f2aa3b11033498ae97abf6dc6c 100644 (file)
@@ -395,7 +395,7 @@ static bh_arr(AstPolySolution) find_polymorphic_slns(AstPolyProc* pp, PolyProcLo
         else if (pp_lookup == PPLM_By_Function_Type) {
             Type* ft = (Type*) actual;
             if (param->idx >= ft->Function.param_count) {
-                if (err_msg) *err_msg = "Incompatible polymorphic argument to function paramter.";
+                if (err_msg) *err_msg = "Incompatible polymorphic argument to function parameter.";
                 goto sln_not_found;
             }