From ff0be98bad9549eeb06355e848bd868c792203a5 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Wed, 26 Feb 2020 16:19:57 +0100 Subject: externalize speedymalloc --- src/Makefile | 6 +- src/allocators/speedymalloc.py | 35 +++++++- src/allocators/speedymallocs.py | 25 ++++++ src/speedymalloc.c | 171 ---------------------------------------- 4 files changed, 57 insertions(+), 180 deletions(-) create mode 100644 src/allocators/speedymallocs.py delete mode 100644 src/speedymalloc.c diff --git a/src/Makefile b/src/Makefile index 5458801..3e085e2 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 speedymalloc.so align_to_cl.so +ALLOCS = chattymalloc.so bumpptr_alloc.so align_to_cl.so TARGETS = $(addprefix $(OBJDIR)/allocators/,$(ALLOCS)) $(addprefix $(OBJDIR)/,$(TOOLS)) .PHONY: all clean @@ -25,10 +25,6 @@ $(OBJDIR)/allocators/bumpptr_alloc.so: bump_alloc.h bumpptr_alloc.c malloc.c Mak @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi $(CC) $(LDFLAGS) -shared -DMEMSIZE=$(MEMSIZE) $(CFLAGS) -o $@ bumpptr_alloc.c malloc.c -$(OBJDIR)/allocators/speedymalloc.so: speedymalloc.c malloc.c Makefile - @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi - $(CC) $(LDFLAGS) -shared -DMEMSIZE=$(MEMSIZE) $(CFLAGS) -o $@ speedymalloc.c malloc.c - $(OBJDIR)/allocators/align_to_cl.so: align_to_cl.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..e71ac5e 100644 --- a/src/allocators/speedymalloc.py +++ b/src/allocators/speedymalloc.py @@ -22,8 +22,35 @@ memory in speeds favor. Memory is mmapped per thread and never freed. See src/bumpptr.c for the actual implementation. """ -import os -from src.allocator import Allocator, BUILDDIR +from src.artifact import GitArtifact +from src.allocator import Allocator -speedymalloc = Allocator("speedymalloc", LD_PRELOAD=os.path.join(BUILDDIR, "speedymalloc.so"), - color="xkcd:dark") +VERSION = "ac18af91cf7c50a686b34402b772423b013553d2" + +class Speedymalloc(Allocator): + """ Speedymalloc definition for allocbench""" + + sources = GitArtifact("speedymalloc", "https://gitlab.cs.fau.de/flow/speedymalloc.git") + + def __init__(self, name, **kwargs): + + configuration = "" + for option, value in kwargs.get("options", {}).items(): + configuration += f"-D{option}={value} " + + self.build_cmds = ["meson {srcdir} {dir}", + f"meson configure {{dir}} {configuration}", + "ninja -C {dir}"] + + self.LD_PRELOAD = "{dir}/libspeedymalloc.so" + super().__init__(name, **kwargs) + +speedymalloc = Speedymalloc("speedymalloc", version=VERSION) + +speedymalloc_dont_madv_free = Speedymalloc("speedymalloc_dont_madv_free", + options = {"madvise_free": "false"}, + version=VERSION) + +speedymalloc_dont_madv_willneed = Speedymalloc("speedymalloc_dont_madv_willneed", + options = {"madvise_willneed": "false"}, + version=VERSION) diff --git a/src/allocators/speedymallocs.py b/src/allocators/speedymallocs.py new file mode 100644 index 0000000..9c14839 --- /dev/null +++ b/src/allocators/speedymallocs.py @@ -0,0 +1,25 @@ +# Copyright 2018-2019 Florian Fischer +# +# 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 . + +"""Collection containing all glibc variants""" + +import src.allocators.speedymalloc as sm + + +allocators = [sm.speedymalloc, + sm.speedymalloc_dont_madv_free, + sm.speedymalloc_dont_madv_willneed] diff --git a/src/speedymalloc.c b/src/speedymalloc.c deleted file mode 100644 index 7df3c5a..0000000 --- a/src/speedymalloc.c +++ /dev/null @@ -1,171 +0,0 @@ -#include -#include -#include /* NULL, size_t */ -#include /* uintptr_t */ -#include /* fprintf */ -#include /* exit */ -#include /* sysconf(_SC_PAGESIZE) */ -#include /* memset */ -#include /* mmap */ - -#define MIN_ALIGNMENT 16 - -#ifndef MEMSIZE -#define MEMSIZE 1024*4*1024*1024l -#endif - -#ifndef NO_WILLNEED -#define WILLNEED_SIZE 32 * 1024 * 1024 -#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; - chunk_t* bins[CACHE_BINS]; -} tls_t; - -__thread tls_t* tls; -__thread uintptr_t next_willneed; - -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); -#ifndef NO_WILLNEED - next_willneed = tls->ptr; -#endif -} - -static void* bump_alloc(size_t size) { - // allocate size header - tls->ptr += sizeof(size_t); - - // align ptr - size_t mask = MIN_ALIGNMENT -1; - tls->ptr = (tls->ptr + mask) & ~mask; - -#ifndef NO_WILLNEED - if(unlikely(tls->ptr >= next_willneed)) { - if (madvise((void*)next_willneed, WILLNEED_SIZE, MADV_WILLNEED) != 0) { - perror("madvice"); - } - next_willneed += WILLNEED_SIZE; - } -#endif - - void* ptr = (void*)tls->ptr; - ptr2chunk(ptr)->size = size; - tls->ptr += size; - - return ptr; -} - -void* malloc(size_t size) { - if (unlikely(tls == NULL)) { - init_tls(); - } - - // cached sizes - if (size < CACHE_BINS * CACHE_BIN_SEPERATION) { - int bin = size2bin(size); - if (tls->bins[bin] != NULL) { - chunk_t* chunk = tls->bins[bin]; - // remove first chunk from list - tls->bins[bin] = chunk->next; - return chunk2ptr(chunk); - } - return bump_alloc(bin2size(bin)); - } - - return bump_alloc(size); -} - -void free(void* ptr) { - if (unlikely(tls == 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 = tls->bins[bin]; - tls->bins[bin] = chunk; - } -} - -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(); - } - - // allocate size header - tls->ptr += sizeof(size_t); - - // align returned pointer - size_t mask = alignment - 1; - tls->ptr = (tls->ptr + mask) & ~mask; - - void* ptr = (void*)tls->ptr; - ptr2chunk(ptr)->size = size; - tls->ptr += size; - - return ptr; -} - -void malloc_stats() { - fprintf(stderr, "speedymalloc allocator by muhq\n"); - fprintf(stderr, "Memsize: %zu, start address: %p, bump pointer %p\n", MEMSIZE, tls, tls->ptr); -} - -#ifdef __cplusplus -} -#endif -- cgit v1.2.3