diff options
| author | Florian Fischer <florian.fl.fischer@fau.de> | 2019-11-11 11:49:45 +0100 |
|---|---|---|
| committer | Florian Fischer <florian.fl.fischer@fau.de> | 2019-11-11 11:49:45 +0100 |
| commit | 1e8d1f2b3efbd879bac32414f82f983181231fbe (patch) | |
| tree | fb3ae3e1165744005a935774d3125bc13c357397 | |
| parent | e9888e9c08e2860914a4b6ada81c5e8b477ad637 (diff) | |
| download | allocbench-1e8d1f2b3efbd879bac32414f82f983181231fbe.tar.gz allocbench-1e8d1f2b3efbd879bac32414f82f983181231fbe.zip | |
add speedymalloc variant using less tsd
| -rw-r--r-- | src/Makefile | 6 | ||||
| -rw-r--r-- | src/allocators/speedymalloc.py | 3 | ||||
| -rw-r--r-- | src/allocators/speedymallocs.py | 23 | ||||
| -rw-r--r-- | src/speedymalloc_2.c | 262 |
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 |
