From 0ea389f7b4048821a72020fb6a15ef9cb41c2b14 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Fri, 31 Aug 2018 23:45:40 +0200 Subject: change benchmark.py for mysql and remove run from mysql.py also simplify chattymalloc because memusage fails for mysqld and fix glibc-no-tc --- chattymalloc.c | 469 ++++----------------------------------------------------- 1 file changed, 30 insertions(+), 439 deletions(-) (limited to 'chattymalloc.c') diff --git a/chattymalloc.c b/chattymalloc.c index 301e0f2..f3db0d2 100644 --- a/chattymalloc.c +++ b/chattymalloc.c @@ -1,278 +1,60 @@ #define _GNU_SOURCE #include -#include #include -#include #include #include #include -#include -#include -#include -#include -static void * (*myfn_malloc)(size_t size); -static void * (*myfn_free)(void* ptr); -static void * (*myfn_calloc)(size_t nmemb, size_t size); -static void * (*myfn_realloc)(void *ptr, size_t size); -static void * (*myfn_memalign)(size_t blocksize, size_t bytes); - -static int initializing = 0; +char tmpbuff[1024]; +unsigned long tmppos = 0; +unsigned long tmpallocs = 0; -// Memory we give out during initialisation -static char tmpbuff[4096]; -static unsigned long tmppos = 0; -static unsigned long tmpallocs = 0; - -/* Options that can be set in the CHATTYMALLOC_OPTS environment var. - * - * store: store call data in memory or dump it with each allocator call */ -static bool store = true; -/* sigusr1: dump in memory log in SIGUSR1 handler */ -static bool sigusr1 = false; -/* timestamp: get timestamp of each allocator call */ -static bool timestamp = false; -/* timestamp: get timestamp of each allocator call */ -static char* path = "chattymalloc.data"; - -void parse_options() -{ - char* options = getenv("CHATTYMALLOC_OPTS"); - if (!options) - return; - - char* opt = options; - char* val; - char c; - - for (int i = 0;; i++) - { - c = options[i]; - if (c == ':' || c == '\0') - { - if (strncmp(opt, "store", 5) == 0) - { - if (strncmp(val, "false", 5) == 0) - store = false; - } - else if (strncmp(opt, "sigusr1", 7) == 0) - { - if (strncmp(val, "true", 4) == 0) - sigusr1 = true; - } - else if (strncmp(opt, "timestamp", 9) == 0) - { - if (strncmp(val, "true", 4) == 0) - timestamp = true; - } - else - fprintf(stderr, "Unknown option \n"); +FILE* out = NULL; - if (c == '\0') - return; +/*========================================================= + * * interception points + * */ - opt = options + i + 1; - } - else if (c == '=') - { - val = options + i + 1; - } - } -} - -typedef enum { MALLOC, FREE, CALLOC, REALLOC, MEMALIGN } Func; - -// Entry in our in memory log -typedef struct Log_entry -{ - time_t time; - Func function; - uintptr_t args[3]; -} Log_entry; - -// Chunk of thread local log entries -typedef struct Log_chunk -{ - struct Log_chunk* next; - pid_t tid; - size_t n; - Log_entry entries[10000]; -} Log_chunk; - -// List of chunks -static struct Log_chunk* log_start = NULL; -static struct Log_chunk* log_end = NULL; - -static __thread pid_t tid; -static __thread Log_chunk* cur_log; - -// Flag to prevent recursion -static __thread int prevent_recursion = 0; - -static void (*old_signalhandler)(int); - -FILE* out; - -#ifdef SYS_gettid -static pid_t gettid() -{ - if (!tid) - tid = syscall(SYS_gettid); - return tid; -} -#else -#error "SYS_gettid unavailable on this system" -#endif - -static void open_output() -{ - out = fopen(path, "w"); - if (!out) - { - perror("failed to open output"); - exit(1); - } -} +static void * (*myfn_malloc)(size_t size); +static void * (*myfn_free)(void* ptr); -static void new_log_chunk (void) +static void init() { - cur_log = myfn_malloc(sizeof(Log_chunk)); - if (!cur_log) + out = fopen("chattymalloc.data", "w"); + if (out == NULL) { - perror("can't malloc chunk"); + fprintf(stderr, "failed to open output file\n"); exit(1); } - cur_log->tid = gettid(); - cur_log->n = 0; - cur_log->next = NULL; - -chain: ; - Log_chunk* old_end = log_end; - if (!__sync_bool_compare_and_swap(&log_end, old_end, cur_log)) - goto chain; - - if (old_end) - old_end->next = cur_log; -} - -static void write_log (void) -{ - Log_chunk* chunk = log_start; - - prevent_recursion = 1; - - open_output(); - - while (chunk) - { - for (size_t i = 0; i < chunk->n; i++) - { - Log_entry entry = chunk->entries[i]; - fprintf(out, "%lu %d ", entry.time, chunk->tid); - switch (entry.function) - { - case MALLOC: - fprintf(out, "ma %lu %p\n", entry.args[0], entry.args[1]); - break; - case FREE: - fprintf(out, "f %p\n", entry.args[0]); - break; - case CALLOC: - fprintf(out, "c %lu %lu %p\n", entry.args[0], entry.args[1], entry.args[2]); - break; - case REALLOC: - fprintf(out, "r %p %lu %p\n", entry.args[0], entry.args[1], entry.args[2]); - break; - case MEMALIGN: - fprintf(out, "mm %lu %lu %p\n", entry.args[0], entry.args[1], entry.args[2]); - break; - } - } - chunk = chunk->next; - } - - fclose(out); -} - -static void sigusr1_handler -(int __attribute__((__unused__)) sig) -{ - write_log(); - pid_t ppid = getppid(); - kill(ppid, SIGUSR1); - - // we are done writing the log - prevent_recursion = 0; -} - -static void init (void) -{ - initializing = 1; - myfn_malloc = dlsym(RTLD_NEXT, "malloc"); myfn_free = dlsym(RTLD_NEXT, "free"); - myfn_calloc = dlsym(RTLD_NEXT, "calloc"); - myfn_realloc = dlsym(RTLD_NEXT, "realloc"); - myfn_memalign = dlsym(RTLD_NEXT, "memalign"); - if (!myfn_malloc || !myfn_free || !myfn_calloc || !myfn_realloc || !myfn_memalign) + if (!myfn_malloc || !myfn_free) { fprintf(stderr, "Error in `dlsym`: %s\n", dlerror()); exit(1); } - - initializing = 0; - // now we can use the real allocator - prevent_recursion = 1; - - // parse chattymalloc options - parse_options(); - - if (store) - { - new_log_chunk(); - log_start = cur_log; - atexit(write_log); - } - else - open_output(); - - if (sigusr1) - { - // register USR1 signal handler to dump log - struct sigaction old; - struct sigaction sa; - - sigaction(SIGUSR1, NULL, &old); - old_signalhandler = old.sa_handler; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = sigusr1_handler; - sa.sa_mask = old.sa_mask; - - if (sigaction(SIGUSR1, &sa, NULL) == -1) - { - perror("Can't register our SIGUSR1 handler"); - exit(1); - } - } - - prevent_recursion = 0; } -void *malloc (size_t size) +void *malloc(size_t size) { + static int initializing = 0; + static int in_fprintf = 0; if (myfn_malloc == NULL) { if (!initializing) + { + initializing = 1; init(); + initializing = 0; + + } else { if (tmppos + size < sizeof(tmpbuff)) { - /* fprintf(stderr, "jcheck: %lu requested during init\n", size); */ void *retptr = tmpbuff + tmppos; tmppos += size; ++tmpallocs; @@ -281,217 +63,26 @@ void *malloc (size_t size) else { fprintf(stderr, "jcheck: too much memory requested during initialisation - increase tmpbuff size\n"); - *((int*) NULL) = 1; exit(1); } } } - void *ptr = myfn_malloc(size); - - if (!prevent_recursion) + if (!in_fprintf) { - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 0; - - if (timestamp) - clock_gettime(CLOCK_MONOTONIC, &ts); - - if (store) - { - if (cur_log == NULL || cur_log->n == 100) - new_log_chunk(); - - Log_entry* cur_entry = &cur_log->entries[cur_log->n]; - - cur_entry->time = ts.tv_nsec; - cur_entry->function = MALLOC; - cur_entry->args[0] = (uintptr_t)size; - cur_entry->args[1] = (uintptr_t)ptr; - cur_log->n++; - } - else - { - prevent_recursion = 1; - fprintf(out, "%lu %d ma %u %p\n", ts.tv_nsec, gettid(), size, ptr); - prevent_recursion = 0; - } + in_fprintf = 1; + fprintf(out, "%d\n", size); + in_fprintf = 0; } - + void *ptr = myfn_malloc(size); return ptr; } -void free (void *ptr) +void free(void *ptr) { - if (myfn_free == NULL) + // something wrong if we call free before one of the allocators! + if (myfn_malloc == NULL) init(); if (!(ptr >= (void*) tmpbuff && ptr <= (void*)(tmpbuff + tmppos))) - { - if (!prevent_recursion) - { - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 0; - - if (timestamp) - clock_gettime(CLOCK_MONOTONIC, &ts); - - if (store) - { - if (cur_log == NULL || cur_log->n == 100) - new_log_chunk(); - - Log_entry* cur_entry = &cur_log->entries[cur_log->n]; - - cur_entry->time = ts.tv_nsec; - cur_entry->function = FREE; - cur_entry->args[0] = (uintptr_t)ptr; - cur_log->n++; - } - else - { - prevent_recursion = 1; - fprintf(out, "%lu %d f %p\n", ts.tv_nsec, gettid(), ptr); - prevent_recursion = 0; - } - } - myfn_free(ptr); - } } - -void *realloc (void *ptr, size_t size) -{ - if (myfn_realloc == NULL) - { - void *nptr = malloc(size); - if (nptr && ptr) - { - memmove(nptr, ptr, size); - free(ptr); - } - return nptr; - } - - void *nptr = myfn_realloc(ptr, size); - - if (!prevent_recursion) - { - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 0; - - if (timestamp) - clock_gettime(CLOCK_MONOTONIC, &ts); - - if (store) - { - if (cur_log == NULL || cur_log->n == 100) - new_log_chunk(); - - Log_entry* cur_entry = &cur_log->entries[cur_log->n]; - - cur_entry->time = ts.tv_nsec; - cur_entry->function = REALLOC; - cur_entry->args[0] = (uintptr_t)ptr; - cur_entry->args[1] = (uintptr_t)size; - cur_entry->args[2] = (uintptr_t)nptr; - cur_log->n++; - } - else - { - prevent_recursion = 1; - fprintf(out, "%lu %d r %p %u %p\n", ts.tv_nsec, gettid(), ptr, size, nptr); - prevent_recursion = 0; - } - } - - return nptr; -} - -void *calloc (size_t nmemb, size_t size) -{ - if (myfn_calloc == NULL) - { - void *ptr = malloc(nmemb*size); - if (ptr) - memset(ptr, 0, nmemb*size); - return ptr; - } - - void *ptr = myfn_calloc(nmemb, size); - - if (!prevent_recursion) - { - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 0; - - if (timestamp) - clock_gettime(CLOCK_MONOTONIC, &ts); - - if (store) - { - if (cur_log == NULL || cur_log->n == 100) - new_log_chunk(); - - Log_entry* cur_entry = &cur_log->entries[cur_log->n]; - - cur_entry->time = ts.tv_nsec; - cur_entry->function = CALLOC; - cur_entry->args[0] = (uintptr_t)nmemb; - cur_entry->args[1] = (uintptr_t)size; - cur_entry->args[2] = (uintptr_t)ptr; - cur_log->n++; - } - else - { - prevent_recursion = 1; - fprintf(out, "%lu %d c %u %u %p\n", ts.tv_nsec, gettid(), nmemb, size, ptr); - prevent_recursion = 0; - } - } - - return ptr; -} - -void *memalign (size_t alignment, size_t size) -{ - // Hopefully this gets never called during init() - void *ptr = myfn_memalign(alignment, size); - - if (!prevent_recursion) - { - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 0; - - if (timestamp) - clock_gettime(CLOCK_MONOTONIC, &ts); - - if (store) - { - if (cur_log == NULL || cur_log->n == 100) - new_log_chunk(); - - Log_entry* cur_entry = &cur_log->entries[cur_log->n]; - - cur_entry->time = ts.tv_nsec; - cur_entry->function = MEMALIGN; - cur_entry->args[0] = (uintptr_t)alignment; - cur_entry->args[1] = (uintptr_t)size; - cur_entry->args[2] = (uintptr_t)ptr; - cur_log->n++; - } - else - { - prevent_recursion = 1; - fprintf(out, "%lu %d mm %u %u %p\n", ts.tv_nsec, gettid(), alignment, size, ptr); - prevent_recursion = 0; - } - } - - return ptr; -} - -- cgit v1.2.3