Zone Freeing - No Fragmentation #12

Merged
wesley merged 1 commits from zone/real-free into main 2024-02-18 14:26:19 -05:00
3 changed files with 58 additions and 53 deletions
Showing only changes of commit 957ba0880d - Show all commits

View File

@@ -4,13 +4,20 @@
#include "../defines.h"
#include "../logger/logger.h"
#include "../types/linked_list.h"
#include "zone.h"
typedef struct ZoneHeader {
u64 capacity;
u64 cur_size;
List *free_zones;
} ZoneHeader;
typedef struct FreeZone {
void *start_address;
u64 capacity;
} FreeZone;
Zone *zoneCreate(size_t sizeBytes) {
// First we need to get a block of memory from the OS
// This block needs to include the size of what we want to store
@@ -25,6 +32,7 @@ Zone *zoneCreate(size_t sizeBytes) {
// Initialize the values of the header
zone_header->capacity = sizeBytes;
zone_header->cur_size = 0;
zone_header->free_zones = listCreate();
return zone_addr;
}
@@ -32,6 +40,29 @@ Zone *zoneCreate(size_t sizeBytes) {
void *zoneAlloc(Zone *zone, size_t sizeBytes) {
ZoneHeader *zone_header = (ZoneHeader *)zone - sizeof(ZoneHeader);
u64 cur_free_zones = listSize(zone_header->free_zones);
if (cur_free_zones > 0) {
for (u64 i = 1; i <= cur_free_zones; i++) {
FreeZone *curFreeZone =
(FreeZone *)listDataAt(zone_header->free_zones, i);
u64 freeZoneSize = curFreeZone->capacity;
if (freeZoneSize >= sizeBytes) {
void *ret_addr = curFreeZone->start_address;
curFreeZone->start_address += sizeBytes;
curFreeZone->capacity -= sizeBytes;
if (curFreeZone->capacity <= 0) {
listRemoveAt(zone_header->free_zones, i);
free(curFreeZone);
}
return ret_addr;
}
}
}
if (zone_header->cur_size + sizeBytes > zone_header->capacity) {
QERROR("Could not allocate, not enough space.");
return NULL;
@@ -41,17 +72,10 @@ void *zoneAlloc(Zone *zone, size_t sizeBytes) {
zone_header->cur_size += sizeBytes;
printf("Zone Header Information:\n");
printf("Current Size: %" PRIu64 "\n", zone_header->cur_size);
printf("Total Capacity: %" PRIu64 "\n", zone_header->capacity);
return new_mem;
}
void zoneFree(void *data, size_t dataSize) {
// TODO: We want to eventually pass in a pointer to the zone so we can track
// our free blocks
void zoneFree(void *data, Zone *zone, size_t dataSize) {
// Lets first check to make sure we weren't given a NULL pointer
if (data == NULL)
return;
@@ -60,26 +84,31 @@ void zoneFree(void *data, size_t dataSize) {
// to 0
memset(data, 0, dataSize);
FreeZone *newFreeZone = malloc(sizeof(FreeZone));
ZoneHeader *zone_header = (ZoneHeader *)zone - sizeof(ZoneHeader);
newFreeZone->start_address = data;
newFreeZone->capacity = dataSize;
listPush(zone_header->free_zones, newFreeZone);
// Now we need to null the pointer
data = NULL;
// TODO: Add logic to alert that this space can now be used
}
void zoneClear(Zone *zone) {
ZoneHeader *zone_header = (ZoneHeader *)zone - sizeof(ZoneHeader);
zone_header->cur_size = 0;
printf("Zone Header Information:\n");
printf("Current Size: %" PRIu64 "\n", zone_header->cur_size);
printf("Total Capacity: %" PRIu64 "\n", zone_header->capacity);
}
void zoneDestroy(Zone *zone) {
// First we need to go back to the beginning of the header as we returned
// an offset for the user to use
void *del_mem = (ZoneHeader *)zone - sizeof(ZoneHeader);
ZoneHeader *del_mem = (ZoneHeader *)zone - sizeof(ZoneHeader);
// Next we need to destory our free_zones list
listDestroy(del_mem->free_zones);
// Free the memory
free(del_mem);

View File

@@ -2,10 +2,10 @@
#include <stddef.h> // size_t definition
typedef struct _Zone Zone;
typedef struct Zone Zone;
Zone *zoneCreate(size_t sizeBytes);
void *zoneAlloc(Zone *zone, size_t sizeBytes);
void zoneFree(void *data, size_t dataSize);
void zoneFree(void *data, Zone *zone, size_t dataSize);
void zoneClear(Zone *zone);
void zoneDestroy(Zone *zone);

View File

@@ -1,4 +1,3 @@
#include "types/linked_list.h"
#include <defines.h>
#include <logger/logger.h>
#include <memory/zone.h>
@@ -13,47 +12,24 @@ int main() {
QINFO("Size of f32: %lu", sizeof(f32));
QINFO("Size of f64: %lu", sizeof(f64));
QINFO("Creating a List...");
List *my_list = listCreate();
QINFO("Pushing to my_list...")
i32 pushVal = 42;
listPush(my_list, &pushVal);
i32 peekVal = *(i32 *)listPeek(my_list);
Zone *test_zone = zoneCreate(4096);
QDEBUG("Peeking value off of my_list: %" PRId32, peekVal);
u64 val1 = 420;
u32 val2 = 169;
u32 val3 = 80085;
QINFO("Pushing another number to my_list...");
i32 pushVal2 = 169420;
listPush(my_list, &pushVal2);
peekVal = *(i32 *)listPeek(my_list);
u64 *zVal1 = (u64 *)zoneAlloc(test_zone, sizeof(val1));
*zVal1 = val1;
QDEBUG("Peeking value off of my_list: %" PRId32, peekVal);
zoneFree(zVal1, test_zone, sizeof(zVal1));
i32 pushVal3 = 69;
listPush(my_list, &pushVal3);
QDEBUG("Peeking a 3rd value off of my_list: %" PRId32, peekVal);
u32 *zVal2 = (u32 *)zoneAlloc(test_zone, sizeof(val2));
u32 *zVal3 = (u32 *)zoneAlloc(test_zone, sizeof(val3));
i32 popVal = *(i32 *)listPop(my_list);
QDEBUG("Popped a value off of my_list: %" PRId32, popVal);
*zVal2 = val2;
*zVal3 = val3;
peekVal = *(i32 *)listPeek(my_list);
QDEBUG("Peeking value off of my_list: %" PRId32, peekVal);
i32 insertValue = 80085;
QINFO("Inserting a value at position 2.");
listInsertAt(my_list, 2, &insertValue);
QDEBUG("Data at position 2 is: %" PRId32, *(i32 *)listDataAt(my_list, 2));
QINFO("Removing a value at position 2.");
listRemoveAt(my_list, 2);
QDEBUG("Data at position 2 is now: %" PRId32, *(i32 *)listDataAt(my_list, 2));
QINFO("Destorying List...");
listDestroy(my_list);
void *dont_care = zoneAlloc(test_zone, 64);
return 0;
}