aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile6
-rw-r--r--src/allocators/speedymalloc.py3
-rw-r--r--src/allocators/speedymallocs.py23
-rw-r--r--src/speedymalloc_2.c262
4 files changed, 293 insertions, 1 deletions
diff --git a/src/Makefile b/src/Makefile
index 6ccfef9..9b22b28 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -14,7 +14,7 @@ MEMSIZE_KB=$(shell free -t | tail -1 | tr -s ' ' | cut -d ' ' -f 2)
MEMSIZE="$(MEMSIZE_KB) * 1024l"
TOOLS = print_status_on_exit.so exec sig_handlers.so
-ALLOCS = chattymalloc.so bumpptr_alloc.so bumpptr_alloc_always_align.so bumpptr_alloc_single_tsd.so speedymalloc.so
+ALLOCS = chattymalloc.so bumpptr_alloc.so bumpptr_alloc_always_align.so bumpptr_alloc_single_tsd.so speedymalloc.so speedymalloc2.so
TARGETS = $(addprefix $(OBJDIR)/allocators/,$(ALLOCS)) $(addprefix $(OBJDIR)/,$(TOOLS))
.PHONY: all clean
@@ -37,6 +37,10 @@ $(OBJDIR)/allocators/speedymalloc.so: speedymalloc.c Makefile
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
$(CC) $(LDFLAGS) -shared -DMEMSIZE=$(MEMSIZE) $(CFLAGS) -o $@ $<
+$(OBJDIR)/allocators/speedymalloc2.so: speedymalloc_2.c Makefile
+ @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
+ $(CC) $(LDFLAGS) -shared -DMEMSIZE=$(MEMSIZE) $(CFLAGS) -o $@ $<
+
$(OBJDIR)/allocators/chattymalloc.so: chattymalloc.c Makefile
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
$(CC) $(LDFLAGS) -shared $(CFLAGS) -o $@ $< -ldl
diff --git a/src/allocators/speedymalloc.py b/src/allocators/speedymalloc.py
index 0cf6836..b4f3d57 100644
--- a/src/allocators/speedymalloc.py
+++ b/src/allocators/speedymalloc.py
@@ -27,3 +27,6 @@ from src.allocator import Allocator, BUILDDIR
speedymalloc = Allocator("speedymalloc", LD_PRELOAD=os.path.join(BUILDDIR, "speedymalloc.so"),
color="xkcd:dark")
+
+speedymalloc2 = Allocator("speedymalloc2", LD_PRELOAD=os.path.join(BUILDDIR, "speedymalloc2.so"),
+ color="xkcd:dark blue")
diff --git a/src/allocators/speedymallocs.py b/src/allocators/speedymallocs.py
new file mode 100644
index 0000000..b190dc9
--- /dev/null
+++ b/src/allocators/speedymallocs.py
@@ -0,0 +1,23 @@
+# Copyright 2018-2019 Florian Fischer <florian.fl.fischer@fau.de>
+#
+# This file is part of allocbench.
+#
+# allocbench is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# allocbench is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with allocbench. If not, see <http://www.gnu.org/licenses/>.
+
+"""Collection containing all speedymalloc variants"""
+
+from src.allocators.speedymalloc import speedymalloc, speedymalloc2
+
+
+allocators = [speedymalloc, speedymalloc2]
diff --git a/src/speedymalloc_2.c b/src/speedymalloc_2.c
new file mode 100644
index 0000000..a079714
--- /dev/null
+++ b/src/speedymalloc_2.c
@@ -0,0 +1,262 @@
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h> /* NULL, size_t */
+#include <stdint.h> /* uintptr_t */
+#include <stdio.h> /* fprintf */
+#include <stdlib.h> /* exit */
+#include <unistd.h> /* sysconf(_SC_PAGESIZE) */
+#include <string.h> /* memset */
+#include <sys/mman.h> /* mmap */
+
+#define MIN_ALIGNMENT 16
+
+#ifndef MEMSIZE
+#define MEMSIZE 1024*4*1024*1024l
+#endif
+
+// sizeof(tls_t) == 4096
+#define CACHE_BINS 511
+// max cached object: 511 * 64 - 1 = 32703
+#define CACHE_BIN_SEPERATION 64
+
+#define unlikely(x) __builtin_expect((x),0)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct chunk {
+ size_t size; // Size header field for internal use
+ struct chunk* next;
+} chunk_t;
+
+static inline chunk_t* ptr2chunk(void* ptr) {
+ return (chunk_t*)((uintptr_t)ptr - sizeof(size_t));
+}
+
+static inline void* chunk2ptr (chunk_t* chunk) {
+ return (void*)((uintptr_t)chunk + sizeof(size_t));
+}
+
+typedef struct TLStates {
+ uintptr_t ptr;
+ uintptr_t end;
+ chunk_t* bins[CACHE_BINS];
+} tls_t;
+
+__thread tls_t* tls;
+
+static inline int size2bin(size_t size) {
+ assert(size > 0 && size < CACHE_BINS * CACHE_BIN_SEPERATION);
+ return (size - 1) / CACHE_BIN_SEPERATION;
+}
+
+static inline size_t bin2size(int bin) {
+ assert(bin >= 0 && bin < CACHE_BINS);
+ return (bin + 1) * CACHE_BIN_SEPERATION;
+}
+
+static void init_tls(void) {
+ void *mem = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ if (mem == MAP_FAILED) {
+ perror("mmap");
+ exit(1);
+ }
+ tls = (tls_t*)mem;
+
+ tls->ptr = ((uintptr_t)tls) + sizeof(tls_t);
+ tls->end = (uintptr_t)tls + MEMSIZE;
+}
+
+inline static void* bump_alloc(size_t size, size_t align) {
+ assert(align % 2 == 0);
+
+ tls_t* ltls = tls;
+
+ // allocate size header
+ uintptr_t ptr_w_header = ltls->ptr + sizeof(size_t);
+
+ // align ptr
+ size_t mask = align -1;
+ uintptr_t aligned = (ptr_w_header + mask) & ~mask;
+
+ uintptr_t new_ptr = aligned + size;
+ if (new_ptr > ltls->end)
+ return NULL;
+ else {
+ void* ptr = (void*)ltls->ptr;
+ // save size in chunk header
+ ptr2chunk(ptr)->size = size;
+ ltls->ptr = new_ptr;
+ return ptr;
+ }
+}
+
+void* malloc(size_t size) {
+ tls_t* ltls = tls;
+
+ if (unlikely(ltls == NULL)) {
+ init_tls();
+ }
+
+ // cached sizes
+ if (size < CACHE_BINS * CACHE_BIN_SEPERATION) {
+ int bin = size2bin(size);
+ if (ltls->bins[bin] != NULL) {
+ chunk_t* chunk = ltls->bins[bin];
+ // remove first chunk from list
+ ltls->bins[bin] = chunk->next;
+ return chunk2ptr(chunk);
+ }
+ return bump_alloc(bin2size(bin), MIN_ALIGNMENT);
+ }
+
+ return bump_alloc(size, MIN_ALIGNMENT);
+}
+
+void free(void* ptr) {
+ tls_t* ltls = tls;
+ if (unlikely(ltls == NULL)) {
+ init_tls();
+ }
+
+ if (ptr == NULL) {
+ return;
+ }
+
+ chunk_t* chunk = ptr2chunk(ptr);
+
+ if (chunk->size < CACHE_BINS * CACHE_BIN_SEPERATION) {
+ int bin = size2bin(chunk->size);
+ chunk->next = ltls->bins[bin];
+ ltls->bins[bin] = chunk;
+ }
+}
+
+void* realloc(void* ptr, size_t size) {
+ if (ptr == NULL) {
+ return malloc(size);
+ }
+
+ if (size == 0) {
+ return NULL;
+ }
+
+ void* new_ptr = malloc(size);
+ size_t to_copy = ptr2chunk(ptr)->size;
+ memcpy(new_ptr, ptr, to_copy);
+ return new_ptr;
+}
+
+void* memalign(size_t alignment, size_t size) {
+ /* if not power of two */
+ if (!((alignment != 0) && !(alignment & (alignment - 1)))) {
+ return NULL;
+ }
+
+ if (unlikely(tls == NULL)) {
+ init_tls();
+ }
+
+ return bump_alloc(size, alignment);
+}
+
+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)
+ 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);
+}
+
+int malloc_stats() {
+ fprintf(stderr, "Bump pointer allocator by muhq\n");
+ fprintf(stderr, "Memsize: %zu, start address: %p, bump pointer %p\n", MEMSIZE, &tls, tls->ptr);
+ return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif