commit cf42ef6c23c178222c23fb9e520e7c3a7f6cf310
parent c9bf1cb3f656d62dbef085becaadef7a7fa7723b
Author: sin <sin@2f30.org>
Date: Wed, 24 Jul 2013 18:22:09 +0300
Add toy memory allocator
Diffstat:
A | alloc.c | | | 115 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 115 insertions(+), 0 deletions(-)
diff --git a/alloc.c b/alloc.c
@@ -0,0 +1,115 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+enum chunk_state {
+ FREE = 0,
+ ALLOCATED,
+};
+
+/* A maximum of `NALLOC' allocations possible */
+enum {
+ NALLOC = 65536 * 64,
+};
+
+/* Only needed because we have to implement
+ * realloc() */
+struct chunk {
+ void *base;
+ size_t size;
+ enum chunk_state state;
+} chunks[NALLOC];
+
+void *
+malloc(size_t nbytes)
+{
+ void *p;
+ long i;
+
+ if (!nbytes)
+ return NULL;
+ p = sbrk(nbytes);
+ if (p == (void *)-1)
+ return NULL;
+ for (i = 0; i < NALLOC; i++) {
+ if (chunks[i].state == FREE) {
+ chunks[i].base = p;
+ chunks[i].size = nbytes;
+ chunks[i].state = ALLOCATED;
+ return p;
+ }
+ }
+ return NULL;
+}
+
+void *
+realloc(void *oldp, size_t nbytes)
+{
+ void *p;
+ size_t n;
+ long i;
+
+ if (!nbytes) {
+ free(oldp);
+ return NULL;
+ }
+ p = malloc(nbytes);
+ if (!p)
+ return NULL;
+ for (i = 0; i < NALLOC; i++) {
+ if (chunks[i].base == oldp) {
+ n = chunks[i].size < nbytes ? chunks[i].size : nbytes;
+ memcpy(p, chunks[i].base, n);
+ free(oldp);
+ return p;
+ }
+ }
+ return NULL;
+}
+
+void *
+calloc(size_t nmemb, size_t size)
+{
+ void *p;
+
+ p = malloc(nmemb * size);
+ if (!p)
+ return NULL;
+ memset(p, 0, size * nmemb);
+ return p;
+}
+
+void
+free(void *p)
+{
+ long i;
+
+ if (!p)
+ return;
+ for (i = 0; i < NALLOC; i++) {
+ if (chunks[i].base == p) {
+ chunks[i].state = FREE;
+ break;
+ }
+ }
+}
+
+void
+cfree(void *p)
+{
+ free(p);
+}
+
+size_t
+malloc_usable_size(void *p)
+{
+ long i;
+
+ if (!p)
+ return 0;
+ for (i = 0; i < NALLOC; i++)
+ if (chunks[i].base == p)
+ return chunks[i].size;
+ return 0;
+}