summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--README.txt32
-rw-r--r--memory/memory.c150
-rw-r--r--memory/test.cpp2
4 files changed, 98 insertions, 87 deletions
diff --git a/.gitignore b/.gitignore
index 6e92f57..09ff560 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
tags
+*.out
diff --git a/README.txt b/README.txt
index 2568cf1..4bee68d 100644
--- a/README.txt
+++ b/README.txt
@@ -1,2 +1,32 @@
1. Introduction
-Code libraries built for my personal use. Use with caution... and care. \ No newline at end of file
+Code libraries built for my personal use. Use with caution... and care.
+
+------------------------------
+2. Table of Contents
+
+a. Memory
+ - Arena Allocator
+ - Stack Allocator
+
+b. String (Under Construction)
+------------------------------
+
+a. Memory
+A simplistic but highly functional helper functions in C. These utilize the concept of allocators to enforce programming
+on a clear and simple concept model. For more info on why and how these work, please search online on some data-oriented
+videos.
+
+They are used in a known programming environment, where every allocation is known and is meant to be tracked. Due to
+this, while it is possible to cause weird overwrite problems, something that I was quite concerned with for a while,
+the reason those won't be a concern is because everything about allocation, and about total allocation capacity is known.
+
+Q. In what cases would this break?
+In specific cases the memory allocators that detect capacity of the buffer can fail to detect if the programmer tries
+allocating memory that is larger than int32 in value, but smaller than the available capacity. In this case, since the
+amount of memory in int32 will wrap around, it would be indiscernable to the allocation checks if the allocation was
+valid or invalid. This would pass the check but eventually fail when allocating and crash the program.
+
+Q. Why is this not a concern?
+This will be used in a known programming environment. Every allocation is meant to be known and tracked. While the
+larger than available memory issue will still be possible, the burden of responsibility is on the programmer (me) to
+understand that I am not meant to allocate space greater than the size_t (target platform).
diff --git a/memory/memory.c b/memory/memory.c
index 7fb0fc2..1d521e4 100644
--- a/memory/memory.c
+++ b/memory/memory.c
@@ -1,13 +1,8 @@
#include "memory.h"
-b8 is_power_of_two(uintptr_t x) {
- return (x & (x-1)) == 0;
-}
+b8 is_power_of_two(uintptr_t x) { return (x & (x - 1)) == 0; }
-uintptr_t fast_modulo(uintptr_t p, uintptr_t a)
-{
- return (p & (a-1));
-}
+uintptr_t fast_modulo(uintptr_t p, uintptr_t a) { return (p & (a - 1)); }
uintptr_t align_forward(uintptr_t ptr, size_t alignment) {
uintptr_t p, a, modulo;
@@ -26,24 +21,26 @@ uintptr_t align_forward(uintptr_t ptr, size_t alignment) {
}
//===========================================================================================
-// ---------------------------------- Arena -------------------------------------------------
+// ---------------------------------- Arena
+// -------------------------------------------------
//===========================================================================================
/*
A cases where arena allocation WILL fail:
| size = size_t + ${some_number_that_comes_up_higher_than_offset}
-
- This is because there is no check being made
+
+ This is because there is no check being made
*/
-void arena_init(struct Arena* a, unsigned char* backing_store, size_t capacity) {
+void arena_init(struct Arena *a, unsigned char *backing_store,
+ size_t capacity) {
a->buffer = backing_store;
a->curr_offset = 0;
a->prev_offset = 0;
a->capacity = capacity;
}
-void* arena_alloc_aligned(struct Arena* a, size_t size, size_t alignment) {
- void* ptr = NULL;
+void *arena_alloc_aligned(struct Arena *a, size_t size, size_t alignment) {
+ void *ptr = NULL;
assert(is_power_of_two(alignment));
@@ -51,8 +48,7 @@ void* arena_alloc_aligned(struct Arena* a, size_t size, size_t alignment) {
uintptr_t offset = align_forward(curr_ptr, alignment);
offset = offset - (uintptr_t)a->buffer;
- if (size <= a->capacity - offset)
- {
+ if (size <= a->capacity - offset) {
ptr = &a->buffer[offset];
a->prev_offset = a->curr_offset;
a->curr_offset = offset + size;
@@ -62,28 +58,23 @@ void* arena_alloc_aligned(struct Arena* a, size_t size, size_t alignment) {
return ptr;
}
-void* arena_alloc(struct Arena* a, size_t size) {
+void *arena_alloc(struct Arena *a, size_t size) {
return arena_alloc_aligned(a, size, DEFAULT_ALIGNMENT);
}
-void* arena_resize_aligned(struct Arena* a, void* old_memory, size_t old_size,
- size_t new_size, size_t alignment)
-{
- unsigned char* old = (unsigned char*)old_memory;
- void* ptr = NULL;
+void *arena_resize_aligned(struct Arena *a, void *old_memory, size_t old_size,
+ size_t new_size, size_t alignment) {
+ unsigned char *old = (unsigned char *)old_memory;
+ void *ptr = NULL;
assert(is_power_of_two(alignment));
- if (old >= a->buffer && old < a->buffer + a->capacity)
- {
- if (a->buffer + a->prev_offset == old)
- {
+ if (old >= a->buffer && old < a->buffer + a->capacity) {
+ if (a->buffer + a->prev_offset == old) {
// extend_last_element
- if (new_size > old_size)
- {
+ if (new_size > old_size) {
size_t size_increase = new_size - old_size;
- if (size_increase > (a->capacity - a->curr_offset))
- {
+ if (size_increase > (a->capacity - a->curr_offset)) {
new_size = old_size;
size_increase = 0;
}
@@ -91,24 +82,22 @@ void* arena_resize_aligned(struct Arena* a, void* old_memory, size_t old_size,
}
a->curr_offset = a->prev_offset + new_size;
ptr = old_memory;
- }
- else
- {
+ } else {
ptr = arena_alloc_aligned(a, new_size, alignment);
- if (ptr != NULL)
- {
+ if (ptr != NULL) {
size_t copy_size = old_size < new_size ? old_size : new_size;
memmove(ptr, old_memory, copy_size);
}
}
}
-
+
return ptr;
}
-void* arena_resize(struct Arena* a, void* old_mem, size_t old_size,
- size_t new_size) {
- return arena_resize_aligned(a, old_mem, old_size, new_size, DEFAULT_ALIGNMENT);
+void *arena_resize(struct Arena *a, void *old_mem, size_t old_size,
+ size_t new_size) {
+ return arena_resize_aligned(a, old_mem, old_size, new_size,
+ DEFAULT_ALIGNMENT);
}
void arena_clear(struct Arena *a) {
@@ -117,20 +106,19 @@ void arena_clear(struct Arena *a) {
}
//===========================================================================================
-// ---------------------------------- STACK -------------------------------------------------
+// ---------------------------------- STACK
+// -------------------------------------------------
//===========================================================================================
-void stack_init(struct stack* s, void *backing_store, size_t capacity)
-{
- s->buffer = (unsigned char*)backing_store;
+void stack_init(struct stack *s, void *backing_store, size_t capacity) {
+ s->buffer = (unsigned char *)backing_store;
s->prev_offset = 0;
s->curr_offset = 0;
s->capacity = capacity;
}
-
-size_t calc_padding_with_header(uintptr_t ptr, uintptr_t alignment, size_t hdr_sz)
-{
+size_t calc_padding_with_header(uintptr_t ptr, uintptr_t alignment,
+ size_t hdr_sz) {
uintptr_t p, a, modulo, padding, space_needed;
assert(is_power_of_two(alignment));
@@ -146,15 +134,11 @@ size_t calc_padding_with_header(uintptr_t ptr, uintptr_t alignment, size_t hdr_s
}
space_needed = (uintptr_t)hdr_sz;
- if (padding < space_needed)
- {
+ if (padding < space_needed) {
space_needed -= padding;
- if (fast_modulo(space_needed, a) != 0)
- {
+ if (fast_modulo(space_needed, a) != 0) {
padding = padding + space_needed + a;
- }
- else
- {
+ } else {
padding = padding + space_needed;
}
}
@@ -162,8 +146,8 @@ size_t calc_padding_with_header(uintptr_t ptr, uintptr_t alignment, size_t hdr_s
return (size_t)padding;
}
-struct ResVoid stack_alloc_aligned(struct stack* s, size_t size, size_t alignment)
-{
+struct ResVoid stack_alloc_aligned(struct stack *s, size_t size,
+ size_t alignment) {
uintptr_t curr_addr, next_addr;
size_t padding;
struct stack_hdr *header;
@@ -173,19 +157,19 @@ struct ResVoid stack_alloc_aligned(struct stack* s, size_t size, size_t alignmen
alignment = 128;
}
- struct ResVoid result = {0};
+ struct ResVoid result = {.status = MEM_OK, .bytes_count = 0, .memory = 0};
curr_addr = (uintptr_t)s->buffer + (uintptr_t)s->curr_offset;
- padding = calc_padding_with_header(curr_addr, (uintptr_t)alignment, sizeof(struct stack_hdr));
+ padding = calc_padding_with_header(curr_addr, (uintptr_t)alignment,
+ sizeof(struct stack_hdr));
- if (size > s->capacity - (s->curr_offset + padding))
- {
+ if (size > s->capacity - (s->curr_offset + padding)) {
result.status = MEM_FULL;
return result;
}
next_addr = curr_addr + (uintptr_t)padding;
- header = (struct stack_hdr*)(next_addr - sizeof(struct stack_hdr));
+ header = (struct stack_hdr *)(next_addr - sizeof(struct stack_hdr));
header->prev_offset = s->prev_offset;
header->padding = padding;
@@ -198,42 +182,38 @@ struct ResVoid stack_alloc_aligned(struct stack* s, size_t size, size_t alignmen
return result;
}
-struct ResVoid stack_alloc(struct stack* s, size_t size)
-{
+struct ResVoid stack_alloc(struct stack *s, size_t size) {
return stack_alloc_aligned(s, size, DEFAULT_ALIGNMENT);
}
-enum MemStatus stack_free(struct stack* s)
-{
+enum MemStatus stack_free(struct stack *s) {
uintptr_t last_ele = (uintptr_t)s->buffer + (uintptr_t)s->prev_offset;
- struct stack_hdr *header = (struct stack_hdr *)(last_ele - sizeof(struct stack_hdr));
+ struct stack_hdr *header =
+ (struct stack_hdr *)(last_ele - sizeof(struct stack_hdr));
uintptr_t prev_ele = (uintptr_t)s->buffer + (uintptr_t)header->prev_offset;
- s->curr_offset = (size_t)((last_ele - (uintptr_t)header->padding) - (uintptr_t)s->buffer);
+ s->curr_offset =
+ (size_t)((last_ele - (uintptr_t)header->padding) - (uintptr_t)s->buffer);
s->prev_offset = (size_t)(prev_ele - (uintptr_t)s->buffer);
-
+
return MEM_OK;
}
-struct ResVoid stack_resize_aligned(struct stack* s, void* old_memory, size_t old_size,
- size_t new_size, size_t alignment)
-{
- struct ResVoid result = {0};
+struct ResVoid stack_resize_aligned(struct stack *s, void *old_memory,
+ size_t old_size, size_t new_size,
+ size_t alignment) {
+ struct ResVoid result = {.status = MEM_OK, .bytes_count = 0, .memory = 0};
- if (old_memory < s->buffer || old_memory > s->buffer + s->capacity)
- {
+ if (old_memory < s->buffer || old_memory > s->buffer + s->capacity) {
result.status = MEM_OUT_OF_BOUNDS;
return result;
}
// is_last_element()
- if (s->buffer + s->prev_offset == old_memory)
- {
- if (new_size > old_size)
- {
+ if (s->buffer + s->prev_offset == old_memory) {
+ if (new_size > old_size) {
size_t size_difference = new_size - old_size;
- if (size_difference > s->capacity - s->curr_offset)
- {
+ if (size_difference > s->capacity - s->curr_offset) {
result.status = MEM_FULL;
return result;
}
@@ -247,20 +227,20 @@ struct ResVoid stack_resize_aligned(struct stack* s, void* old_memory, size_t ol
}
result = stack_alloc_aligned(s, new_size, alignment);
- size_t min_size = old_size < result.bytes_count ? old_size : result.bytes_count;
+ size_t min_size =
+ old_size < result.bytes_count ? old_size : result.bytes_count;
memmove(result.memory, old_memory, min_size);
return result;
}
-struct ResVoid stack_resize(struct stack* s, void* old_memory, size_t old_size, size_t new_size)
-{
- return stack_resize_aligned(s, old_memory, old_size, new_size, DEFAULT_ALIGNMENT);
+struct ResVoid stack_resize(struct stack *s, void *old_memory, size_t old_size,
+ size_t new_size) {
+ return stack_resize_aligned(s, old_memory, old_size, new_size,
+ DEFAULT_ALIGNMENT);
}
-void stack_clear(struct stack* s)
-{
+void stack_clear(struct stack *s) {
s->prev_offset = 0;
s->curr_offset = 0;
}
-
diff --git a/memory/test.cpp b/memory/test.cpp
index 97c0f25..f62ce96 100644
--- a/memory/test.cpp
+++ b/memory/test.cpp
@@ -118,7 +118,7 @@ void test_arena_resize_out_of_bounds(unsigned char *buffer, u32 buffer_size)
qres = arena_resize(&a, n1, 8, buffer_size - 8);
assert(qres == NULL && "Arena Resize OUT OF BOUNDS test Failed: \n"
- "Reason: Failed to fit a larger than capacity element within Arena capacity.\n");
+ "Reason: Allocated a larger than capacity element within Arena capacity.\n");
}
void test_arena_resize_negative_size(unsigned char *buffer, u32 buffer_size)