From: Brendan Hansen Date: Thu, 14 Jan 2021 18:41:52 +0000 (-0600) Subject: added pool allocator to core library X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=c765c61e17eb257c699d4af1070090c960cd44ca;p=onyx.git added pool allocator to core library --- diff --git a/bin/onyx b/bin/onyx index 4ceb4990..6bc20b20 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/core/alloc.onyx b/core/alloc.onyx index 792e497c..9950f9a4 100644 --- a/core/alloc.onyx +++ b/core/alloc.onyx @@ -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 index 00000000..4abf6a5f --- /dev/null +++ b/core/alloc/pool.onyx @@ -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 .{ + 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 diff --git a/core/stdio.onyx b/core/stdio.onyx index c3e67fda..c0a235e7 100644 --- a/core/stdio.onyx +++ b/core/stdio.onyx @@ -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 () { diff --git a/onyx.exe b/onyx.exe index b8a51481..b54fafb6 100644 Binary files a/onyx.exe and b/onyx.exe differ diff --git a/src/onyxutils.c b/src/onyxutils.c index cfdd13e5..0fd12a08 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -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; }