initial commit
This commit is contained in:
commit
4731cb37b8
|
@ -0,0 +1,3 @@
|
|||
/.cache
|
||||
/.vscode
|
||||
/build
|
|
@ -0,0 +1,3 @@
|
|||
project(defralloc)
|
||||
|
||||
add_executable(test defralloc.c test.c)
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
Reference in New Issue