From f0d35eb314ac52e4ec0f45f150de3d5224610c3b Mon Sep 17 00:00:00 2001
From: Florian Fischer <florian.fl.fischer@fau.de>
Date: Sun, 28 Apr 2019 18:42:07 +0200
Subject: [PATCH] add bumptr allocator implementation

---
 src/Makefile        |  11 +++-
 src/allocator.py    |  10 ++-
 src/bumpptr_alloc.c | 151 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 167 insertions(+), 5 deletions(-)
 create mode 100644 src/bumpptr_alloc.c

diff --git a/src/Makefile b/src/Makefile
index e29af5d..9858cdf 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -12,12 +12,19 @@ LDFLAGS ?= -pthread -static-libgcc
 
 .PHONY: all clean
 
-all: $(OBJDIR)/print_status_on_exit.so
+all: $(OBJDIR)/print_status_on_exit.so $(OBJDIR)/allocators/bumpptr_alloc.so
 
-$(OBJDIR)/print_status_on_exit.so: print_status_on_exit.c | $(OBJDIR)
+$(OBJDIR)/allocators/bumpptr_alloc.so: bumpptr_alloc.c | $(OBJDIR)/allocators
 	@echo "Compiling $@...";
 	$(CC) $(LDFLAGS) -shared $(CFLAGS) -o $@ $<
 
+$(OBJDIR)/print_status_on_exit.so: print_status_on_exit.c | $(OBJDIR)
+	@echo "Compiling $@...";
+	$(CC) $(LDFLAGS) -shared -O2 $(CFLAGS) -o $@ $<
+
+$(OBJDIR)/allocators:
+	mkdir -p $@
+
 $(OBJDIR):
 	mkdir $@
 
diff --git a/src/allocator.py b/src/allocator.py
index 4e40ebf..04710c1 100644
--- a/src/allocator.py
+++ b/src/allocator.py
@@ -1,5 +1,6 @@
 import copy
 from datetime import datetime
+import inspect
 import os
 import shutil
 import subprocess
@@ -8,6 +9,7 @@ import sys
 import src.globalvars
 from src.util import *
 
+
 library_path = ""
 for l in subprocess.run(["ldconfig", "-v"], stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
@@ -26,6 +28,7 @@ class Allocator_Sources (object):
         self.name = name
         self.dir = os.path.join(srcdir, self.name)
         self.retrieve_cmds = retrieve_cmds
+        self.patchdir = os.path.join("src/allocators/", self.name)
         self.prepare_cmds = prepare_cmds
         self.reset_cmds = reset_cmds
 
@@ -70,7 +73,7 @@ class Allocator_Sources (object):
 
         print_status("Patching", self.name, "...")
         for patch in patches:
-            with open(patch, "rb") as f:
+            with open(patch.format(patchdir=self.patchdir), "rb") as f:
                 p = subprocess.run("patch -p1", shell=True, cwd=cwd,
                                    stderr=subprocess.PIPE, stdout=stdout,
                                    input=f.read())
@@ -106,8 +109,7 @@ class Allocator (object):
             with open(buildtimestamp_file, "r") as f:
                 timestamp = datetime.fromtimestamp(float(f.read()))
 
-            # print(globals())
-            modtime = os.stat(os.path.realpath(src.globalvars.allocators_file)).st_mtime
+            modtime = os.stat(inspect.getfile(self.__class__)).st_mtime
             modtime = datetime.fromtimestamp(modtime)
 
             build_needed = timestamp < modtime
@@ -170,3 +172,5 @@ def patch_alloc(name, alloc, patches, **kwargs):
 
     return new_alloc
 
+
+bumpptr = Allocator("bumpptr", LD_PRELOAD=os.path.join(builddir, "bumpptr_alloc.so"), color="C8")
diff --git a/src/bumpptr_alloc.c b/src/bumpptr_alloc.c
new file mode 100644
index 0000000..fc8f77e
--- /dev/null
+++ b/src/bumpptr_alloc.c
@@ -0,0 +1,151 @@
+#include <errno.h>
+#include <stddef.h> /* NULL, size_t */
+#include <stdint.h> /* uintptr_t */
+#include <stdio.h> /* uintptr_t */
+#include <unistd.h> /* sysconf(_SC_PAGESIZE) */
+#include <string.h> /* memset */
+#include <sys/mman.h> /* memset */
+
+#define MEMSIZE 1024*4*1024*1024l
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+__thread void* mem_start = NULL;
+__thread void* mem_end = NULL;
+
+__thread uintptr_t ptr = 0;
+__thread uintptr_t last_freed_ptr = 0;
+
+void* malloc(size_t size) {
+	if(mem_start == NULL) {
+		mem_start = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+		if(mem_start == MAP_FAILED) {
+			perror("mmap");
+			return NULL;
+		}
+		ptr = (uintptr_t)mem_start;
+	}
+
+	void* ret = (void*)ptr;
+	ptr += size;
+	return ret;
+}
+
+void free(void* ptr) {
+}
+
+void* realloc(void* ptr, size_t size) {
+	if(ptr == NULL)
+		return malloc(size);
+
+	if(size == 0)
+		return NULL;
+
+	void* new_ptr = malloc(size);
+	// this may copies to much
+	memcpy(new_ptr, ptr, size);
+	return new_ptr;
+}
+
+void* memalign(size_t alignment, size_t size) {
+	// bump ptr to alignment and malloc
+	ptr = (ptr + (alignment - 1)) & -alignment;
+	return malloc(size);
+}
+
+int posix_memalign(void **memptr, size_t alignment, size_t size)
+{
+	void *out;
+
+	if(memptr == NULL) {
+		return 22;
+	}
+
+	if((alignment % sizeof(void*)) != 0) {
+		return 22;
+	}
+
+	/* if not power of two */
+	if(!((alignment != 0) && !(alignment & (alignment - 1)))) {
+		return 22;
+	}
+
+	if(size == 0) {
+		*memptr = NULL;
+		return 0;
+	}
+
+	out = memalign(alignment, size);
+	if(out == NULL) {
+		return 12;
+	}
+
+	*memptr = out;
+	return 0;
+}
+
+void* calloc(size_t nmemb, size_t size)
+{
+	void *out;
+	size_t fullsize = nmemb * size;
+
+	if((size != 0) && ((fullsize / size) != nmemb)) {
+		return NULL;
+	}
+	
+	out = malloc(fullsize);
+	if(out == NULL) {
+		return NULL;
+	}
+
+	memset(out, 0, fullsize);
+	return out;
+}
+
+void* valloc(size_t size)
+{
+	long ret = sysconf(_SC_PAGESIZE);
+	if(ret == -1) {
+		return NULL;
+	}
+
+	return memalign(ret, size);
+}
+
+void* pvalloc(size_t size)
+{
+	size_t ps, rem, allocsize;
+
+	long ret = sysconf(_SC_PAGESIZE);
+	if(ret == -1) {
+		return NULL;
+	}
+
+	ps = ret;
+	rem = size % ps;
+	allocsize = size;
+	if(rem != 0) {
+		allocsize = ps + (size - rem);
+	}
+
+	return memalign(ps, allocsize);
+}
+
+void* aligned_alloc(size_t alignment, size_t size)
+{
+	if(alignment > size) {
+		return NULL;
+	}
+
+	if((size % alignment) != 0) {
+		return NULL;
+	}
+
+	return memalign(alignment, size);
+}
+
+#ifdef __cplusplus
+}
+#endif
-- 
GitLab