Skip to content

Commit

Permalink
Allocator hooks no longer cares who the allocator is
Browse files Browse the repository at this point in the history
Change-Id: I4ee9ee6f5ff333edc9c32db6389eaaa1e1b09549
  • Loading branch information
Mike Wiederhold committed Feb 22, 2012
1 parent 843b53e commit f34f19c
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 51 deletions.
129 changes: 82 additions & 47 deletions daemon/alloc_hooks.c
Original file line number Diff line number Diff line change
@@ -1,75 +1,110 @@

#include "alloc_hooks.h"

static bool triedLoadFunctions = false;
static bool haveHooksFunctions = true;

static Alias addNewHook;
static Alias addDelHook;
static Alias removeNewHook;
static Alias removeDelHook;

static Alias getStatsProp;
static Alias getAllocSize;

void loadAllocatorFunctions() {
if (triedLoadFunctions) {
return;
}
triedLoadFunctions = true;

void* handle = dlopen(NULL, RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
addNewHook.ptr = dlsym(handle, "MallocHook_AddNewHook");
addDelHook.ptr = dlsym(handle, "MallocHook_AddDeleteHook");
removeNewHook.ptr = dlsym(handle, "MallocHook_RemoveNewHook");
removeDelHook.ptr = dlsym(handle, "MallocHook_RemoveDeleteHook");

getStatsProp.ptr = dlsym(handle, "MallocExtension_GetNumericProperty");

getAllocSize.ptr = dlsym(handle, "MallocExtension_GetAllocatedSize");

if (!addNewHook.ptr && !addDelHook.ptr && !removeNewHook.ptr && !removeDelHook.ptr) {
haveHooksFunctions = false;
get_stderr_logger()->log(EXTENSION_LOG_WARNING, NULL,
"Couldn't find allocator hooks for memory tracking");
}
}

bool mc_add_new_hook(void (*hook)(const void* ptr, size_t size)) {
#if defined(HAVE_LIBTCMALLOC) || defined(HAVE_LIBTCMALLOC_MINIMAL)
return (MallocHook_AddNewHook(hook) == 1) ? true : false;
#else
loadAllocatorFunctions();
if (haveHooksFunctions) {
return (addNewHook.func)(hook) ? true : false;
}
return false;
#endif
}

bool mc_remove_new_hook(void (*hook)(const void* ptr, size_t size)) {
#if defined(HAVE_LIBTCMALLOC) || defined(HAVE_LIBTCMALLOC_MINIMAL)
return (MallocHook_RemoveNewHook(hook) == 1) ? true : false;
#else
loadAllocatorFunctions();
if (haveHooksFunctions) {
return (removeNewHook.func)(hook) ? true : false;
}
return false;
#endif
}

bool mc_add_delete_hook(void (*hook)(const void* ptr)) {
#if defined(HAVE_LIBTCMALLOC) || defined(HAVE_LIBTCMALLOC_MINIMAL)
return (MallocHook_AddDeleteHook(hook) == 1) ? true : false;
#else
loadAllocatorFunctions();
if (haveHooksFunctions) {
return (addDelHook.func)(hook) ? true : false;
}
return false;
#endif
}

bool mc_remove_delete_hook(void (*hook)(const void* ptr)) {
#if defined(HAVE_LIBTCMALLOC) || defined(HAVE_LIBTCMALLOC_MINIMAL)
return (MallocHook_RemoveDeleteHook(hook) == 1) ? true : false;
#else
loadAllocatorFunctions();
if (haveHooksFunctions) {
return (removeDelHook.func)(hook) ? true : false;
}
return false;
#endif
}

allocator_stat* mc_get_allocator_stats(int* size) {
#if defined(HAVE_LIBTCMALLOC) || defined(HAVE_LIBTCMALLOC_MINIMAL)
char* tcmalloc_stats_names[] = {"generic.current_allocated_bytes",
"generic.heap_size",
"tcmalloc.pageheap_free_bytes",
"tcmalloc.pageheap_unmapped_bytes",
"tcmalloc.max_total_thread_cache_bytes",
"tcmalloc.current_total_thread_cache_bytes"};

char* stats_names[] = {"tcmalloc_allocated_bytes",
"tcmalloc_heap_size",
"tcmalloc_free_bytes",
"tcmalloc_unmapped_bytes",
"tcmalloc_max_thread_cache_bytes",
"tcmalloc_current_thread_cache_bytes"};

*size = sizeof(tcmalloc_stats_names) / sizeof(char*);
allocator_stat* stats = (allocator_stat*)malloc(*size * sizeof(allocator_stat));

int i;
for (i = 0; i < *size; i++) {
(*(stats + i)).key = strdup(stats_names[i]);
MallocExtension_GetNumericProperty(tcmalloc_stats_names[i],
&((*(stats + i)).value));
}
if (getStatsProp.ptr) {
char* tcmalloc_stats_names[] = {"generic.current_allocated_bytes",
"generic.heap_size",
"tcmalloc.pageheap_free_bytes",
"tcmalloc.pageheap_unmapped_bytes",
"tcmalloc.max_total_thread_cache_bytes",
"tcmalloc.current_total_thread_cache_bytes"};

return stats;
#else
char* stats_names[] = {"tcmalloc_allocated_bytes",
"tcmalloc_heap_size",
"tcmalloc_free_bytes",
"tcmalloc_unmapped_bytes",
"tcmalloc_max_thread_cache_bytes",
"tcmalloc_current_thread_cache_bytes"};

*size = sizeof(tcmalloc_stats_names) / sizeof(char*);
allocator_stat* stats = (allocator_stat*)malloc(*size * sizeof(allocator_stat));

int i;
for (i = 0; i < *size; i++) {
(*(stats + i)).key = strdup(stats_names[i]);
(getStatsProp.func)(tcmalloc_stats_names[i], &((*(stats + i)).value));
}

return stats;
}
*size = 0;
return NULL;
#endif
}

size_t mc_get_allocation_size(void* ptr) {
#if defined(HAVE_LIBTCMALLOC) || defined(HAVE_LIBTCMALLOC_MINIMAL)
return MallocExtension_GetAllocatedSize(ptr);
#else
if (getAllocSize.ptr) {
return (size_t)(getAllocSize.func)(ptr);
}
return 0;
#endif
}
12 changes: 8 additions & 4 deletions daemon/alloc_hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
#include <stdbool.h>
#endif

#if defined(HAVE_LIBTCMALLOC) || defined (HAVE_LIBTCMALLOC_MINIMAL)
#include <google/malloc_extension_c.h>
#include <google/malloc_hook_c.h>
#endif
#include "memcached/extension_loggers.h"

typedef union alias {
void* (*func)();
void* ptr;
} Alias;

bool mc_add_new_hook(void (*)(const void* ptr, size_t size));
bool mc_remove_new_hook(void (*)(const void* ptr, size_t size));
Expand All @@ -24,4 +26,6 @@ bool mc_remove_delete_hook(void (*)(const void* ptr));
allocator_stat* mc_get_allocator_stats(int*);
size_t mc_get_allocation_size(void*);

void loadAllocatorFunctions(void);

#endif /* MEM_HOOKS_H */

0 comments on commit f34f19c

Please sign in to comment.