74 lines
1.6 KiB
C
74 lines
1.6 KiB
C
|
|
#include <stdlib.h>
|
||
|
|
#include <syscall.h>
|
||
|
|
|
||
|
|
#define ALIGN(size) (((size) + 3) & ~3)
|
||
|
|
#define HEADER_SIZE sizeof(struct Header)
|
||
|
|
|
||
|
|
struct Header {
|
||
|
|
size_t size;
|
||
|
|
int is_free;
|
||
|
|
struct Header* next;
|
||
|
|
};
|
||
|
|
|
||
|
|
static struct Header* free_list_head = NULL;
|
||
|
|
|
||
|
|
static struct Header* find_free_block(struct Header** last, size_t size) {
|
||
|
|
struct Header* current = free_list_head;
|
||
|
|
while (current && !(current->is_free && current->size >= size)) {
|
||
|
|
*last = current;
|
||
|
|
current = current->next;
|
||
|
|
}
|
||
|
|
return current;
|
||
|
|
}
|
||
|
|
|
||
|
|
static struct Header* request_space(struct Header* last, size_t size) {
|
||
|
|
struct Header* block = sbrk(0);
|
||
|
|
void* request = sbrk(size + HEADER_SIZE);
|
||
|
|
|
||
|
|
if (request == (void*)-1) {
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (last) {
|
||
|
|
last->next = block;
|
||
|
|
}
|
||
|
|
|
||
|
|
block->size = size;
|
||
|
|
block->next = NULL;
|
||
|
|
block->is_free = 0;
|
||
|
|
return block;
|
||
|
|
}
|
||
|
|
|
||
|
|
void* malloc(size_t size) {
|
||
|
|
if (size <= 0) {
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
size = ALIGN(size);
|
||
|
|
|
||
|
|
if (free_list_head == NULL) {
|
||
|
|
struct Header* block = request_space(NULL, size);
|
||
|
|
if (!block) return NULL;
|
||
|
|
free_list_head = block;
|
||
|
|
return (void*)(block + 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
struct Header* last = free_list_head;
|
||
|
|
struct Header* block = find_free_block(&last, size);
|
||
|
|
|
||
|
|
if (block) {
|
||
|
|
block->is_free = 0;
|
||
|
|
} else {
|
||
|
|
block = request_space(last, size);
|
||
|
|
if (!block) return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
return (void*)(block + 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
void free(void* ptr) {
|
||
|
|
if (!ptr) return;
|
||
|
|
|
||
|
|
struct Header* block = (struct Header*)ptr - 1;
|
||
|
|
block->is_free = 1;
|
||
|
|
}
|