Skip to content

Instantly share code, notes, and snippets.

@ashafq
Created October 22, 2021 22:41
Show Gist options
  • Save ashafq/7c9edf20a7c1ca49091ec69fba537ab0 to your computer and use it in GitHub Desktop.
Save ashafq/7c9edf20a7c1ca49091ec69fba537ab0 to your computer and use it in GitHub Desktop.
Simple Malloc
/**
* Simple Malloc (smalloc)
* Copyright (C) 2021 Ayan Shafqat <ayan.x.shafqat@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
struct node {
struct node *next;
unsigned int size;
unsigned int used;
};
static char *heap_start = HEAP;
static char *heap_end = HEAP + HEAP_SIZE;
static struct node *head = NULL;
static struct node *get_free_block(size_t size);
static void set_free_block(void *ptr);
static void *get_mem_ptr(struct node *node);
static struct node *get_node_ptr(void *ptr);
void *smalloc(size_t size) {
if (size == 0) {
return NULL;
}
// Initialize
if (head == NULL) {
head = (struct node *)heap_start;
head->size = size;
head->used = 1;
head->next = NULL;
return get_mem_ptr(head);
}
// Get a free block from free list, if any
do {
struct node *block = get_free_block(size);
if (block) {
return get_mem_ptr(block);
}
} while (0);
// Allocation failed
return NULL;
}
void sfree(void *ptr) {
if (ptr) {
set_free_block(ptr);
}
}
static struct node *get_node_ptr(void *ptr) {
if (ptr) {
char *p = ((char *)ptr) - sizeof(struct node);
return (struct node *)p;
} else {
return ptr;
}
}
static void *get_mem_ptr(struct node *node) {
if (node) {
return ((char *)node) + sizeof(struct node);
} else {
return node;
}
}
static struct node *get_free_block(size_t size) {
struct node *cur = head;
while (cur) {
if ((cur->used == 0) && (cur->size >= size)) {
cur->used = 1;
return cur;
}
// Create the new block
if (cur->next == NULL) {
char *ptr = (char *)get_mem_ptr(cur) + cur->size;
// Out of heap memory
if ((ptr + size + sizeof (struct node)) >= heap_end) {
return NULL;
}
struct node *nblk = (struct node *)ptr;
nblk->used = 1;
nblk->size = size;
nblk->next = NULL;
cur->next = nblk;
cur = cur->next;
return cur;
}
cur = cur->next;
}
// Out of heap memory
return NULL;
}
static void set_free_block(void *ptr) {
struct node *cur = head;
while (cur) {
if ((get_node_ptr(ptr) == cur) && (cur->used != 0)) {
cur->used = 0;
return;
}
cur = cur->next;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment