initial commit

This commit is contained in:
lemonsh 2022-07-02 12:22:46 +02:00
commit 4731cb37b8
6 changed files with 199 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/.cache
/.vscode
/build

3
CMakeLists.txt Normal file
View File

@ -0,0 +1,3 @@
project(defralloc)
add_executable(test defralloc.c test.c)

6
README.md Normal file
View File

@ -0,0 +1,6 @@
# defralloc
Dumbest allocator on the planet, designed for embedded:
* Own buffer
* Defragments on free()
* Slow as hell
* Returns a pointer to the actual pointer (because defragging changes the offset XD)

70
defralloc.c Normal file
View File

@ -0,0 +1,70 @@
#include "defralloc.h"
void df_init(df_heap *heap) {
for (int i = 0; i < DEFRALLOC_HEAP_ELEMS; i++) {
heap->elems[i].ptr = 0;
}
}
void **df_malloc(df_heap *heap, int count) {
df_heap_elem *elem = 0, *lastelem = 0;
void *lastelem_ptr = 0;
for (int i = 0; i < DEFRALLOC_HEAP_ELEMS; i++) {
if (elem == 0 && heap->elems[i].ptr == 0) {
elem = heap->elems + i;
}
if (heap->elems[i].ptr > lastelem_ptr) {
lastelem = heap->elems + i;
lastelem_ptr = lastelem->ptr;
}
}
if (elem == 0) {
return 0;
}
void *blockstart =
lastelem == 0 ? heap->buffer : lastelem->ptr + lastelem->size;
if (DEFRALLOC_HEAP_SIZE - (blockstart - (void *)heap->buffer) < count) {
return 0;
}
elem->ptr = blockstart;
elem->size = count;
return &elem->ptr;
}
int df_free(df_heap *heap, void *ptr) {
if (ptr == 0) {
return 0;
}
df_heap_elem *elem = 0;
for (int i = 0; i < DEFRALLOC_HEAP_ELEMS; i++) {
if (heap->elems[i].ptr == ptr) {
elem = heap->elems + i;
}
}
if (elem == 0) {
return 0;
}
int firstbyte = DEFRALLOC_HEAP_SIZE;
int lastbyte = -1;
for (int i = 0; i < DEFRALLOC_HEAP_ELEMS; i++) {
if (heap->elems[i].ptr > elem->ptr) {
int l_firstbyte = heap->elems[i].ptr - (void *)heap->buffer;
int l_lastbyte = l_firstbyte + heap->elems[i].size - 1;
heap->elems[i].ptr -= elem->size;
if (firstbyte > l_firstbyte) {
firstbyte = l_firstbyte;
}
if (lastbyte < l_lastbyte) {
lastbyte = l_lastbyte;
}
}
}
if (lastbyte != -1) {
for (int i = firstbyte; i <= lastbyte; i++) {
heap->buffer[i - elem->size] = heap->buffer[i];
}
}
elem->ptr = 0;
return 1;
}

26
defralloc.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef DEFRALLOC_HEADER
#define DEFRALLOC_HEADER
#ifndef DEFRALLOC_HEAP_SIZE
#define DEFRALLOC_HEAP_SIZE 512
#endif
#ifndef DEFRALLOC_HEAP_ELEMS
#define DEFRALLOC_HEAP_ELEMS 8
#endif
typedef struct {
void* ptr;
int size;
} df_heap_elem;
typedef struct {
df_heap_elem elems[DEFRALLOC_HEAP_ELEMS];
char buffer[DEFRALLOC_HEAP_SIZE];
} df_heap;
void df_init(df_heap *heap);
void **df_malloc(df_heap *heap, int count);
int df_free(df_heap *heap, void* ptr);
#endif

91
test.c Normal file
View File

@ -0,0 +1,91 @@
#include "defralloc.h"
#include <memory.h>
#include <stddef.h>
#include <stdio.h>
int allocs[] = {64, 64, 64, 64, 64, 64, 64, 64, 55};
int memsets[] = {0xde, 0xad, 0xbe, 0xef, 0xde, 0xca, 0xfb, 0xad};
int frees[] = {2, 4, 6};
void **allocs_ptrs[sizeof(allocs) / sizeof(*allocs)];
void dump_heap(df_heap *heap) {
printf("-- HEAP DUMP START --\nsize: %d | max elems: %d\n",
DEFRALLOC_HEAP_SIZE, DEFRALLOC_HEAP_ELEMS);
df_heap_elem *lastelem = 0;
void *lastelem_ptr = 0;
int lastelem_idx = -1;
for (int i = 0; i < DEFRALLOC_HEAP_ELEMS; i++) {
df_heap_elem *elem = heap->elems + i;
if (heap->elems[i].ptr > lastelem_ptr) {
lastelem = elem;
lastelem_idx = i;
lastelem_ptr = lastelem->ptr;
}
if (elem->ptr != 0) {
printf(" [%d] ptr: %lu | offset: %lu | size: %d | data: ", i,
(size_t)elem->ptr, (size_t)elem->ptr - (size_t)heap->buffer,
elem->size);
char *data = elem->ptr;
for (size_t i = 0; i < elem->size; i++) {
printf("%02hhx", data[i]);
}
} else {
printf(" [%d] empty", i);
}
putchar('\n');
}
int freemem;
if (lastelem == 0) {
freemem = DEFRALLOC_HEAP_SIZE;
} else {
void *blockstart = lastelem->ptr + lastelem->size;
freemem = DEFRALLOC_HEAP_SIZE - (blockstart - (void *)heap->buffer);
}
printf("last elem: %d | free: %db\n-- HEAP DUMP END --\n", lastelem_idx,
freemem);
}
int main() {
df_heap heap;
df_init(&heap);
puts("PHASE 1: MALLOC\n");
dump_heap(&heap);
for (int i = 0; i < sizeof(allocs) / sizeof(*allocs); i++) {
allocs_ptrs[i] = df_malloc(&heap, allocs[i]);
printf(" [%d] df_malloc(&heap, %d): %lu -> %lu\n", i, allocs[i],
(size_t)allocs_ptrs[i],
allocs_ptrs[i] == 0 ? 0 : (size_t) * (allocs_ptrs[i]));
if (allocs_ptrs[i]) {
memset(*allocs_ptrs[i], memsets[i], allocs[i]);
}
}
dump_heap(&heap);
puts("\nPHASE 2: FREE\n");
for (int i = 0; i < sizeof(frees) / sizeof(*frees); i++) {
void *ptr = *(allocs_ptrs[frees[i]]);
printf(" [%d] df_free(&heap, %lu): %d\n", i, (size_t)ptr,
df_free(&heap, ptr));
dump_heap(&heap);
}
puts("\nPHASE 3: RE-MALLOC\n");
dump_heap(&heap);
for (int i = 0; i < sizeof(frees) / sizeof(*frees); i++) {
allocs_ptrs[frees[i]] = df_malloc(&heap, allocs[frees[i]]);
printf(" [%d] df_malloc(&heap, %d): %lu -> %lu\n", i, allocs[i],
(size_t)allocs_ptrs[i],
allocs_ptrs[i] == 0 ? 0 : (size_t) * (allocs_ptrs[frees[i]]));
if (allocs_ptrs[frees[i]]) {
memset(*allocs_ptrs[frees[i]], memsets[i], allocs[frees[i]]);
}
}
dump_heap(&heap);
puts("\nPHASE 4: FREE ALL\n");
for (int i = 0; i < DEFRALLOC_HEAP_ELEMS; i++) {
void *ptr = *(allocs_ptrs[i]);
printf(" [%d] df_free(&heap, %lu): %d\n", i, (size_t)ptr,
df_free(&heap, ptr));
dump_heap(&heap);
}
putchar('\n');
return 0;
}