aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fl.fischer@fau.de>2019-06-27 01:13:48 +0200
committerFlorian Fischer <florian.fl.fischer@fau.de>2019-06-27 01:13:48 +0200
commit50e5591c898e2155613c018e9dec76b8a6933af1 (patch)
treee123b039efd03c942a693ffa80b7cab3bc7ec64d
parent23e77009bb8da35e2285c3a8f5913c192f9e009f (diff)
downloadallocbench-50e5591c898e2155613c018e9dec76b8a6933af1.tar.gz
allocbench-50e5591c898e2155613c018e9dec76b8a6933af1.zip
add draft of library rounding each allocation up to full cachelinescache_exclusive_alloc
Preloading does not seem to work, yet :)
-rw-r--r--src/Makefile9
-rw-r--r--src/cacheline_exclusive.c121
2 files changed, 128 insertions, 2 deletions
diff --git a/src/Makefile b/src/Makefile
index 9858cdf..9fb3130 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -4,7 +4,8 @@ CC ?= gcc
WARNFLAGS ?= -Wall -Wextra
COMMONFLAGS ?= -fno-builtin -fPIC -DPIC -pthread
-OPTFLAGS ?= -O3 -DNDEBUG
+# OPTFLAGS ?= -O3 -DNDEBUG
+ OPTFLAGS ?= -O0 -g
CFLAGS ?= $(OPTFLAGS) $(WARNFLAGS) $(COMMONFLAGS)
@@ -12,12 +13,16 @@ LDFLAGS ?= -pthread -static-libgcc
.PHONY: all clean
-all: $(OBJDIR)/print_status_on_exit.so $(OBJDIR)/allocators/bumpptr_alloc.so
+all: $(OBJDIR)/print_status_on_exit.so $(OBJDIR)/allocators/bumpptr_alloc.so $(OBJDIR)/cacheline_exclusive.so
$(OBJDIR)/allocators/bumpptr_alloc.so: bumpptr_alloc.c | $(OBJDIR)/allocators
@echo "Compiling $@...";
$(CC) $(LDFLAGS) -shared $(CFLAGS) -o $@ $<
+$(OBJDIR)/cacheline_exclusive.so: cacheline_exclusive.c | $(OBJDIR)
+ @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 $@ $<
diff --git a/src/cacheline_exclusive.c b/src/cacheline_exclusive.c
new file mode 100644
index 0000000..392c3f5
--- /dev/null
+++ b/src/cacheline_exclusive.c
@@ -0,0 +1,121 @@
+#define _GNU_SOURCE
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CACHE_LINE 64
+
+static char tmpbuff[4096];
+static unsigned long tmppos = 0;
+static unsigned long tmpallocs = 0;
+
+/* =========================================================
+ * interception points
+ */
+static void* (*real_malloc) (size_t) = NULL;
+static void (*real_free) (void*) = NULL;
+static void* (*real_calloc) (size_t, size_t) = NULL;
+static void* (*real_realloc) (void*, size_t) = NULL;
+
+static void init(void) {
+ real_malloc = dlsym(RTLD_NEXT, "malloc");
+ real_free = dlsym(RTLD_NEXT, "free");
+ real_calloc = dlsym(RTLD_NEXT, "calloc");
+ real_realloc = dlsym(RTLD_NEXT, "realloc");
+
+ if (!real_malloc || !real_free || !real_calloc || !real_realloc) {
+ fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
+ }
+}
+
+static inline size_t alignUp(size_t size, size_t alignment)
+{
+ if (alignment > 0) {
+ assert(((alignment - 1) & alignment) == 0);
+ size_t mask = (alignment - 1);
+ return (size + mask) & ~mask;
+ }
+ return size;
+}
+
+void *malloc(size_t size)
+{
+ static int initializing = 0;
+ size = alignUp(size, 64);
+
+ if (real_malloc == NULL)
+ {
+ if (!initializing)
+ {
+ initializing = 1;
+ init();
+ initializing = 0;
+ }
+ else
+ {
+ if (tmppos + size < sizeof(tmpbuff))
+ {
+ void *retptr = tmpbuff + tmppos;
+ tmppos += size;
+ ++tmpallocs;
+ return retptr;
+ }
+ else
+ {
+ fprintf(stderr, "%d in %d allocs\n", tmppos, tmpallocs);
+ fprintf(stderr, "jcheck: too much memory requested during initialisation - increase tmpbuff size\n");
+ exit(1);
+ }
+ }
+ }
+
+ return real_malloc(size);
+}
+
+void free(void *ptr)
+{
+ // something wrong if we call free before one of the allocators!
+ if (real_malloc == NULL)
+ init();
+
+ if (!(ptr >= (void*) tmpbuff && ptr <= (void*)(tmpbuff + tmppos)))
+ {
+ real_free(ptr);
+ }
+}
+
+void* calloc(size_t nmemb, size_t size)
+{
+ // Overflows are not detected anymore
+ size_t total = alignUp(nmemb * size, 64);
+ if (real_calloc == NULL)
+ {
+ void *ptr = malloc(total);
+ if (ptr)
+ memset(ptr, 0, total);
+ return ptr;
+ }
+
+ // Is this always correct ?
+ return real_calloc(1, total);
+}
+
+void* realloc(void *ptr, size_t size)
+{
+ size = alignUp(size, 64);
+ if (real_realloc == NULL)
+ {
+ void *nptr = malloc(size);
+ if (nptr && ptr)
+ {
+ memmove(nptr, ptr, size);
+ free(ptr);
+ }
+ return nptr;
+ }
+
+ return real_realloc(ptr, size);
+}