summaryrefslogtreecommitdiff
path: root/malloc/block_allocator
diff options
context:
space:
mode:
authorMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
committerMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
commit967be9e750221ab2ab783f95df79bb26d290a45e (patch)
tree6802900a5e975f9f68b169f0f503f040056d6952 /malloc/block_allocator
add: added projectsHEADmain
Diffstat (limited to 'malloc/block_allocator')
-rw-r--r--malloc/block_allocator/allocator.c61
-rw-r--r--malloc/block_allocator/allocator.h25
-rw-r--r--malloc/block_allocator/main.c39
-rw-r--r--malloc/block_allocator/utils.c16
-rw-r--r--malloc/block_allocator/utils.h16
5 files changed, 157 insertions, 0 deletions
diff --git a/malloc/block_allocator/allocator.c b/malloc/block_allocator/allocator.c
new file mode 100644
index 0000000..0cf9af6
--- /dev/null
+++ b/malloc/block_allocator/allocator.c
@@ -0,0 +1,61 @@
+#include "allocator.h"
+
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+size_t align(size_t size, size_t al)
+{
+ size_t padding = size % al;
+ if (padding)
+ padding = al - padding;
+ size_t res;
+ if (__builtin_uaddl_overflow(size, padding, &res))
+ return 0;
+ return res;
+}
+
+struct blk_allocator *blka_new(void)
+{
+ struct blk_allocator *new = malloc(sizeof(struct blk_allocator));
+ new->meta = NULL;
+ return new;
+}
+
+struct blk_meta *blka_alloc(struct blk_allocator *blka, size_t size)
+{
+ long page_size = sysconf(_SC_PAGESIZE);
+ size_t aligned_size = align(size + sizeof(struct blk_meta), page_size);
+ struct blk_meta *meta = mmap(NULL, aligned_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (meta == MAP_FAILED)
+ return NULL;
+ meta->size = aligned_size - sizeof(struct blk_meta);
+ meta->next = blka->meta;
+ blka->meta = meta;
+ return meta;
+}
+
+void blka_free(struct blk_meta *blk)
+{
+ munmap(blk, blk->size + sizeof(struct blk_meta));
+}
+
+void blka_pop(struct blk_allocator *blka)
+{
+ if (blka->meta == NULL)
+ return;
+
+ struct blk_meta *meta = blka->meta;
+ blka->meta = blka->meta->next;
+ blka_free(meta);
+}
+
+void blka_delete(struct blk_allocator *blka)
+{
+ while (blka->meta)
+ {
+ blka_pop(blka);
+ }
+ free(blka);
+}
diff --git a/malloc/block_allocator/allocator.h b/malloc/block_allocator/allocator.h
new file mode 100644
index 0000000..98dd63e
--- /dev/null
+++ b/malloc/block_allocator/allocator.h
@@ -0,0 +1,25 @@
+#ifndef ALLOCATOR_H
+#define ALLOCATOR_H
+
+#include <stddef.h>
+
+struct blk_meta
+{
+ struct blk_meta *next;
+ size_t size;
+ char data[];
+};
+
+struct blk_allocator
+{
+ struct blk_meta *meta;
+};
+
+struct blk_allocator *blka_new(void);
+void blka_delete(struct blk_allocator *blka);
+
+struct blk_meta *blka_alloc(struct blk_allocator *blka, size_t size);
+void blka_free(struct blk_meta *blk);
+void blka_pop(struct blk_allocator *blka);
+
+#endif /* !ALLOCATOR_H */
diff --git a/malloc/block_allocator/main.c b/malloc/block_allocator/main.c
new file mode 100644
index 0000000..161185a
--- /dev/null
+++ b/malloc/block_allocator/main.c
@@ -0,0 +1,39 @@
+#include <string.h>
+
+#include "allocator.h"
+#include "utils.h"
+
+int main(void)
+{
+ struct blk_allocator *ba = blka_new();
+
+ struct blk_meta *metas[6] = { NULL };
+ char *messages[] = { "Hello world!\n", "You are doing ", "a great job ",
+ "if you see ", "this message ", "correctly.\n",
+ "But do not forget ", "to release ", "memory.\n" };
+
+ // Allocate metadatas
+ for (size_t i = 0; i < 3; ++i)
+ metas[i] = blka_alloc(ba, 2048);
+ for (size_t i = 3; i < 6; ++i)
+ metas[i] = blka_alloc(ba, 4096);
+
+ // Write and read messages to metadatas
+ for (size_t i = 0; i < 6; ++i)
+ write_data(metas[i], messages[i], strlen(messages[i]));
+ for (size_t i = 0; i < 6; ++i)
+ read_data(metas[i]);
+
+ // Overwrite metadatas, pop and read them
+ for (size_t i = 6; i < 9; ++i)
+ write_data(metas[i - 6], messages[i], strlen(messages[i]));
+ for (size_t i = 0; i < 3; ++i)
+ blka_pop(ba);
+ for (size_t i = 0; i < 3; ++i)
+ read_data(metas[i]);
+
+ // Release memory
+ blka_delete(ba);
+
+ return 0;
+}
diff --git a/malloc/block_allocator/utils.c b/malloc/block_allocator/utils.c
new file mode 100644
index 0000000..d38dca0
--- /dev/null
+++ b/malloc/block_allocator/utils.c
@@ -0,0 +1,16 @@
+#include "utils.h"
+
+#include <stdio.h>
+
+void read_data(struct blk_meta *meta)
+{
+ for (size_t i = 0; i < meta->size && meta->data[i] != '\0'; ++i)
+ putchar(meta->data[i]);
+}
+
+void write_data(struct blk_meta *meta, char *data, size_t n)
+{
+ for (size_t i = 0; i < n; ++i)
+ meta->data[i] = data[i];
+ meta->data[n] = '\0';
+}
diff --git a/malloc/block_allocator/utils.h b/malloc/block_allocator/utils.h
new file mode 100644
index 0000000..7573945
--- /dev/null
+++ b/malloc/block_allocator/utils.h
@@ -0,0 +1,16 @@
+#ifndef UTILS_H
+#define UTILS_H
+
+#include "allocator.h"
+
+/*
+ * Print datas the `meta` block contains.
+ */
+void read_data(struct blk_meta *meta);
+
+/*
+ * Write `data` in the `meta` block.
+ */
+void write_data(struct blk_meta *meta, char *data, size_t n);
+
+#endif /* !UTILS_H */