Allocator_Error.Mode_Not_Implemented; Minor improvement to map runtime procedures

This commit is contained in:
gingerBill
2021-08-08 14:29:45 +01:00
parent a5605e94b1
commit 4d00c2b800
6 changed files with 41 additions and 120 deletions
+24 -6
View File
@@ -31,10 +31,11 @@ Allocator_Query_Info :: struct {
Allocator_Error :: runtime.Allocator_Error;
/*
Allocator_Error :: enum byte {
None = 0,
Out_Of_Memory = 1,
Invalid_Pointer = 2,
Invalid_Argument = 3,
None = 0,
Out_Of_Memory = 1,
Invalid_Pointer = 2,
Invalid_Argument = 3,
Mode_Not_Implemented = 4,
}
*/
Allocator_Proc :: runtime.Allocator_Proc;
@@ -121,7 +122,15 @@ resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_AL
return nil;
}
data, err := allocator.procedure(allocator.data, Allocator_Mode.Resize, new_size, alignment, ptr, old_size, loc);
_ = err;
if err == .Mode_Not_Implemented {
data, err = allocator.procedure(allocator.data, Allocator_Mode.Alloc, new_size, alignment, nil, 0, loc);
if err != nil {
return nil;
}
runtime.copy(data, byte_slice(ptr, old_size));
_, err = allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, ptr, old_size, loc);
return raw_data(data);
}
return raw_data(data);
}
@@ -140,7 +149,16 @@ resize_bytes :: proc(old_data: []byte, new_size: int, alignment: int = DEFAULT_A
} else if ptr == nil {
return allocator.procedure(allocator.data, Allocator_Mode.Alloc, new_size, alignment, nil, 0, loc);
}
return allocator.procedure(allocator.data, Allocator_Mode.Resize, new_size, alignment, ptr, old_size, loc);
data, err := allocator.procedure(allocator.data, Allocator_Mode.Resize, new_size, alignment, ptr, old_size, loc);
if err == .Mode_Not_Implemented {
data, err = allocator.procedure(allocator.data, Allocator_Mode.Alloc, new_size, alignment, nil, 0, loc);
if err != nil {
return data, err;
}
runtime.copy(data, old_data);
_, err = allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, ptr, old_size, loc);
}
return data, err;
}
query_features :: proc(allocator: Allocator, loc := #caller_location) -> (set: Allocator_Mode_Set) {
+8 -106
View File
@@ -67,8 +67,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
return byte_slice(ptr, size), nil;
case .Free:
// NOTE(bill): Free all at once
// Use Arena_Temp_Memory if you want to free a block
return nil, .Mode_Not_Implemented;
case .Free_All:
arena.offset = 0;
@@ -84,7 +83,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
return nil, nil;
case .Query_Info:
return nil, nil;
return nil, .Mode_Not_Implemented;
}
return nil, nil;
@@ -262,7 +261,7 @@ scratch_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
return nil, nil;
case .Query_Info:
return nil, nil;
return nil, .Mode_Not_Implemented;
}
return nil, nil;
@@ -426,7 +425,7 @@ stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
}
return nil, nil;
case .Query_Info:
return nil, nil;
return nil, .Mode_Not_Implemented;
}
return nil, nil;
@@ -561,7 +560,7 @@ small_stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
return nil, nil;
case .Query_Info:
return nil, nil;
return nil, .Mode_Not_Implemented;
}
return nil, nil;
@@ -602,7 +601,7 @@ dynamic_pool_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode
case .Alloc:
return dynamic_pool_alloc_bytes(pool, size);
case .Free:
return nil, nil;
return nil, .Mode_Not_Implemented;
case .Free_All:
dynamic_pool_free_all(pool);
return nil, nil;
@@ -786,7 +785,7 @@ panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
return nil, nil;
case .Query_Info:
return nil, nil;
panic("mem: panic allocator, .Query_Info called");
}
return nil, nil;
@@ -908,106 +907,9 @@ tracking_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
return nil, nil;
case .Query_Info:
return nil, nil;
unreachable();
}
return result, err;
}
// Small_Allocator primary allocates memory from its local buffer of size BUFFER_SIZE
// If that buffer's memory is exhausted, it will use the backing allocator (a scratch allocator is recommended)
// Memory allocated with Small_Allocator cannot be freed individually using 'free' and must be freed using 'free_all'
Small_Allocator :: struct($BUFFER_SIZE: int)
where
BUFFER_SIZE >= 2*size_of(uintptr),
BUFFER_SIZE & (BUFFER_SIZE-1) == 0 {
buffer: [BUFFER_SIZE]byte,
backing: Allocator,
start: uintptr,
curr: uintptr,
end: uintptr,
chunk_size: int,
}
small_allocator :: proc(s: ^$S/Small_Allocator, backing := context.allocator) -> (a: Allocator) {
if s.backing.procedure == nil {
s.backing = backing;
}
a.data = s;
a.procedure = proc(allocator_data: rawptr, mode: Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, flags: u64 = 0, loc := #caller_location) -> rawptr {
s := (^S)(allocator_data);
if s.chunk_size <= 0 {
s.chunk_size = 4*1024;
}
if s.start == 0 {
s.start = uintptr(&s.buffer[0]);
s.curr = s.start;
s.end = s.start + uintptr(S.BUFFER_SIZE);
(^rawptr)(s.start)^ = nil;
s.curr += size_of(rawptr);
}
switch mode {
case .Alloc:
s.curr = align_forward_uintptr(s.curr, uintptr(alignment));
if size > int(s.end - s.curr) {
to_allocate := size_of(rawptr) + size + alignment;
if to_allocate < s.chunk_size {
to_allocate = s.chunk_size;
}
s.chunk_size *= 2;
p := alloc(to_allocate, 16, s.backing, loc);
(^rawptr)(s.start)^ = p;
s.start = uintptr(p);
s.curr = s.start;
s.end = s.start + uintptr(to_allocate);
(^rawptr)(s.start)^ = nil;
s.curr += size_of(rawptr);
s.curr = align_forward_uintptr(s.curr, uintptr(alignment));
}
p := rawptr(s.curr);
s.curr += uintptr(size);
return mem_zero(p, size);
case .Free:
// NOP
return nil;
case .Resize:
// No need copying the code
return default_resize_align(old_memory, old_size, size, alignment, small_allocator(s, s.backing), loc);
case .Free_All:
p := (^rawptr)(&s.buffer[0])^;
for p != nil {
next := (^rawptr)(p)^;
free(next, s.backing, loc);
p = next;
}
// Reset to default
s.start = uintptr(&s.buffer[0]);
s.curr = s.start;
s.end = s.start + uintptr(S.BUFFER_SIZE);
(^rawptr)(s.start)^ = nil;
s.curr += size_of(rawptr);
case .Query_Features:
return nil, nil;
case .Query_Info:
return nil, nil;
}
return nil, nil;
};
return a;
}
+2 -2
View File
@@ -188,7 +188,7 @@ heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
aligned_free(old_memory);
case .Free_All:
// NOTE(tetra): Do nothing.
return nil, .Mode_Not_Implemented;
case .Resize:
if old_memory == nil {
@@ -204,7 +204,7 @@ heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
return nil, nil;
case .Query_Info:
return nil, nil;
return nil, .Mode_Not_Implemented;
}
return nil, nil;
+1 -1
View File
@@ -84,7 +84,7 @@ _heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
aligned_free(old_memory);
case .Free_All:
// NOTE(tetra): Do nothing.
return nil, .Mode_Not_Implemented;
case .Resize:
if old_memory == nil {
+5 -4
View File
@@ -276,10 +276,11 @@ Allocator_Query_Info :: struct {
}
Allocator_Error :: enum byte {
None = 0,
Out_Of_Memory = 1,
Invalid_Pointer = 2,
Invalid_Argument = 3,
None = 0,
Out_Of_Memory = 1,
Invalid_Pointer = 2,
Invalid_Argument = 3,
Mode_Not_Implemented = 4,
}
Allocator_Proc :: #type proc(allocator_data: rawptr, mode: Allocator_Mode,
+1 -1
View File
@@ -196,6 +196,7 @@ __dynamic_map_rehash :: proc(using header: Map_Header, new_count: int, loc := #c
new_header: Map_Header = header;
nm := Raw_Map{};
nm.entries.allocator = m.entries.allocator;
nm.hashes = m.hashes;
new_header.m = &nm;
c := context;
@@ -239,7 +240,6 @@ __dynamic_map_rehash :: proc(using header: Map_Header, new_count: int, loc := #c
}
}
delete(m.hashes, m.entries.allocator, loc);
free(m.entries.data, m.entries.allocator, loc);
header.m^ = nm;
}