improved profiler (hashfunc and free-list)

personal/stbuehler/wip
Thomas Porzelt 15 years ago
parent 24777f99d7
commit bbb3c8c69d

@ -36,6 +36,9 @@ int main(int argc, char *argv[]) {
if (profile_mem != NULL && g_str_equal(profile_mem, "true")) {
/*g_mem_set_vtable(glib_mem_profiler_table);*/
profiler_enable();
atexit(profiler_finish);
atexit(profiler_dump);
/*atexit(profiler_dump_table);*/
}
/* parse commandline options */
@ -134,8 +137,5 @@ int main(int argc, char *argv[]) {
if (free_config_path)
g_free(config_path);
if (profile_mem)
profiler_dump();
return 0;
}

@ -11,11 +11,6 @@
#define PROFILER_HASHTABLE_SIZE 1024
static profiler_mem stats_mem = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
static GStaticMutex profiler_mutex = G_STATIC_MUTEX_INIT;
static gboolean profiler_enabled = FALSE;
struct profiler_entry {
gpointer addr;
gsize len;
@ -23,6 +18,12 @@ struct profiler_entry {
};
typedef struct profiler_entry profiler_entry;
static profiler_mem stats_mem = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
static GStaticMutex profiler_mutex = G_STATIC_MUTEX_INIT;
static gboolean profiler_enabled = FALSE;
static profiler_entry *free_list = NULL;
static struct {
profiler_entry **nodes;
} profiler_hashtable;
@ -31,8 +32,15 @@ static void profiler_hashtable_init() {
profiler_hashtable.nodes = calloc(1, sizeof(profiler_entry*) * PROFILER_HASHTABLE_SIZE);
}
static guint profiler_hash_addr(gpointer addr) {
guint h = (gsize) addr;
h = (h >> 3) * 2654435761; /* ~ golden ratio of 2^32, shift 3 because of 8 byte boundary alignment (use 2 for 4 byte boundary) */
//printf("hashing addr 0x%zx: %u ([%u])\n", (gsize)addr, h, h % PROFILER_HASHTABLE_SIZE);
return h % PROFILER_HASHTABLE_SIZE;
}
static profiler_entry *profiler_hashtable_find(gpointer addr) {
guint h = (gsize)addr % PROFILER_HASHTABLE_SIZE;
guint h = profiler_hash_addr(addr);
for (profiler_entry *e = profiler_hashtable.nodes[h]; e != NULL; e = e->next) {
if (e->addr == addr)
@ -43,13 +51,14 @@ static profiler_entry *profiler_hashtable_find(gpointer addr) {
}
static void profiler_hashtable_insert(gpointer addr, gsize len) {
profiler_entry *e = malloc(sizeof(profiler_entry));
profiler_entry *e = free_list;
free_list = free_list->next ? free_list->next : calloc(1, sizeof(profiler_entry));
e->addr = addr;
e->len = len;
e->next = NULL;
guint h = (gsize)addr % PROFILER_HASHTABLE_SIZE;
guint h = profiler_hash_addr(addr);
if (profiler_hashtable.nodes[h] == NULL) {
profiler_hashtable.nodes[h] = e;
@ -65,7 +74,7 @@ static void profiler_hashtable_insert(gpointer addr, gsize len) {
}
static void profiler_hashtable_remove(gpointer addr) {
guint h = (gsize)addr % PROFILER_HASHTABLE_SIZE;
guint h = profiler_hash_addr(addr);
profiler_entry *prev = profiler_hashtable.nodes[h];
if (!prev)
@ -83,7 +92,8 @@ static void profiler_hashtable_remove(gpointer addr) {
for (profiler_entry *e = prev->next; e != NULL; e = e->next) {
if (e->addr == addr) {
prev->next = e->next;
free(e);
e->next = free_list;
free_list = e;
return;
}
prev = e;
@ -202,6 +212,13 @@ void profiler_enable() {
profiler_enabled = TRUE;
profiler_hashtable_init();
/* prealloc 50 hashtable entries */
free_list = calloc(1, sizeof(profiler_entry));
for (guint i = 0; i < 49; i++) {
profiler_entry *e = calloc(1, sizeof(profiler_entry));
e->next = free_list;
free_list = e;
}
t.malloc = profiler_malloc;
t.realloc = profiler_realloc;
@ -214,6 +231,14 @@ void profiler_enable() {
g_mem_set_vtable(&t);
}
void profiler_finish() {
for (profiler_entry *e = free_list; e != NULL;) {
profiler_entry *prev = e;
e = e->next;
free(prev);
}
}
void profiler_dump() {
if (!profiler_enabled)
return;

@ -17,6 +17,7 @@ struct profiler_mem {
};
void profiler_enable(); /* enables the profiler */
void profiler_finish();
void profiler_dump(); /* dumps memory statistics to stdout */
void profiler_dump_table();
#endif

Loading…
Cancel
Save