summaryrefslogtreecommitdiff
path: root/malloc/my_recycler
diff options
context:
space:
mode:
Diffstat (limited to 'malloc/my_recycler')
-rw-r--r--malloc/my_recycler/recycler.c62
-rw-r--r--malloc/my_recycler/recycler.h24
2 files changed, 86 insertions, 0 deletions
diff --git a/malloc/my_recycler/recycler.c b/malloc/my_recycler/recycler.c
new file mode 100644
index 0000000..f2e7da5
--- /dev/null
+++ b/malloc/my_recycler/recycler.c
@@ -0,0 +1,62 @@
+#include "recycler.h"
+
+#include <stdlib.h>
+
+struct recycler *recycler_create(size_t block_size, size_t total_size)
+{
+ if (block_size % sizeof(size_t) || !block_size || !total_size
+ || total_size % block_size)
+ return NULL;
+ struct recycler *rec = malloc(sizeof(struct recycler));
+ if (rec == NULL)
+ return NULL;
+ rec->block_size = block_size;
+ rec->capacity = total_size / block_size;
+ rec->chunk = malloc(total_size * sizeof(void *));
+ if (rec->chunk == NULL)
+ {
+ free(rec);
+ return NULL;
+ }
+ rec->free = rec->chunk;
+ struct free_list *f = rec->free;
+ for (size_t i = 0; i < rec->capacity - 1; i++)
+ {
+ f->next = f + block_size;
+ f = f->next;
+ }
+
+ f->next = NULL;
+
+ return rec;
+}
+
+void recycler_destroy(struct recycler *r)
+{
+ if (r == NULL)
+ return;
+ free(r->chunk);
+ free(r);
+}
+
+void *recycler_allocate(struct recycler *r)
+{
+ if (r == NULL || r->free == NULL)
+ return NULL;
+
+ void *res = r->free;
+ struct free_list *f = r->free;
+ r->free = f->next;
+ return res;
+}
+
+void recycler_free(struct recycler *r, void *block)
+{
+ if (r == NULL || block == NULL)
+ return;
+
+ struct free_list *old_head = r->free;
+ r->free = block;
+ struct free_list *b = block;
+ b->next = old_head;
+}
diff --git a/malloc/my_recycler/recycler.h b/malloc/my_recycler/recycler.h
new file mode 100644
index 0000000..bff70ef
--- /dev/null
+++ b/malloc/my_recycler/recycler.h
@@ -0,0 +1,24 @@
+#ifndef RECYCLER_H
+#define RECYCLER_H
+
+#include <stddef.h>
+
+struct recycler
+{
+ size_t block_size;
+ size_t capacity; // number of blocks in the chunk
+ void *chunk; // memory chunk containing all blocks
+ void *free; // address of the first free block of the free list
+};
+
+struct free_list
+{
+ struct free_list *next; // next free block
+};
+
+struct recycler *recycler_create(size_t block_size, size_t total_size);
+void recycler_destroy(struct recycler *r);
+void *recycler_allocate(struct recycler *r);
+void recycler_free(struct recycler *r, void *block);
+
+#endif /* !RECYCLER_H */