diff options
author | Jason Evans <je@facebook.com> | 2010-02-11 21:38:12 (GMT) |
---|---|---|
committer | Jason Evans <je@facebook.com> | 2010-02-11 21:38:12 (GMT) |
commit | fe5faa2cc5dc50cd3d4338c5daa5c77a81e9e8f0 (patch) | |
tree | df9cb02901f68a957f4665c5c7554bff9ba9cd17 /jemalloc/src | |
parent | d34f9e7e9306698e298a703c28526cd6bfc073ec (diff) | |
download | jemalloc-fe5faa2cc5dc50cd3d4338c5daa5c77a81e9e8f0.zip jemalloc-fe5faa2cc5dc50cd3d4338c5daa5c77a81e9e8f0.tar.gz jemalloc-fe5faa2cc5dc50cd3d4338c5daa5c77a81e9e8f0.tar.bz2 |
Remove tracing (--enable-trace).
Remove all functionality related to tracing. This functionality was
useful for understanding memory fragmentation during early algorithmic
design of jemalloc, but it had little utility for non-trivial
applications, due to the sheer volume of data written to disk.
Diffstat (limited to 'jemalloc/src')
-rw-r--r-- | jemalloc/src/internal/jemalloc_arena.h | 7 | ||||
-rw-r--r-- | jemalloc/src/internal/jemalloc_internal.h.in | 8 | ||||
-rw-r--r-- | jemalloc/src/internal/jemalloc_trace.h | 32 | ||||
-rw-r--r-- | jemalloc/src/internal/mtrgraph_defs.h.in | 14 | ||||
-rw-r--r-- | jemalloc/src/internal/mtrplay_defs.h.in | 14 | ||||
-rw-r--r-- | jemalloc/src/jemalloc.c | 86 | ||||
-rw-r--r-- | jemalloc/src/jemalloc_arena.c | 43 | ||||
-rw-r--r-- | jemalloc/src/jemalloc_ctl.c | 17 | ||||
-rw-r--r-- | jemalloc/src/jemalloc_defs.h.in | 3 | ||||
-rw-r--r-- | jemalloc/src/jemalloc_stats.c | 2 | ||||
-rw-r--r-- | jemalloc/src/jemalloc_trace.c | 281 | ||||
-rw-r--r-- | jemalloc/src/jemtr2mtr.c | 12 | ||||
-rw-r--r-- | jemalloc/src/mtrgraph.c | 1054 | ||||
-rw-r--r-- | jemalloc/src/mtrplay.c | 225 |
14 files changed, 11 insertions, 1787 deletions
diff --git a/jemalloc/src/internal/jemalloc_arena.h b/jemalloc/src/internal/jemalloc_arena.h index cba954f..5596c17 100644 --- a/jemalloc/src/internal/jemalloc_arena.h +++ b/jemalloc/src/internal/jemalloc_arena.h @@ -283,13 +283,6 @@ struct arena_s { # endif #endif -#ifdef JEMALLOC_TRACE -# define TRACE_BUF_SIZE 65536 - unsigned trace_buf_end; - char trace_buf[TRACE_BUF_SIZE]; - int trace_fd; -#endif - #ifdef JEMALLOC_PROF uint64_t prof_accumbytes; #endif diff --git a/jemalloc/src/internal/jemalloc_internal.h.in b/jemalloc/src/internal/jemalloc_internal.h.in index 8f52fa3..d35cdaf 100644 --- a/jemalloc/src/internal/jemalloc_internal.h.in +++ b/jemalloc/src/internal/jemalloc_internal.h.in @@ -58,8 +58,8 @@ extern void (*JEMALLOC_P(malloc_message))(void *w4opaque, const char *p1, #endif /* - * jemalloc can conceptually be broken into components (arena, tcache, trace, - * etc.), but there are circular dependencies that cannot be broken without + * jemalloc can conceptually be broken into components (arena, tcache, etc.), + * but there are circular dependencies that cannot be broken without * substantial performance degradation. In order to reduce the effect on * visual code flow, read the header files in multiple passes, with one of the * following cpp variables defined during each pass: @@ -181,7 +181,6 @@ extern void (*JEMALLOC_P(malloc_message))(void *w4opaque, const char *p1, #include "internal/jemalloc_chunk.h" #include "internal/jemalloc_huge.h" #include "internal/jemalloc_tcache.h" -#include "internal/jemalloc_trace.h" #include "internal/hash.h" #include "internal/prof.h" @@ -201,7 +200,6 @@ extern void (*JEMALLOC_P(malloc_message))(void *w4opaque, const char *p1, #include "internal/jemalloc_chunk.h" #include "internal/jemalloc_huge.h" #include "internal/jemalloc_tcache.h" -#include "internal/jemalloc_trace.h" #include "internal/hash.h" #include "internal/prof.h" @@ -264,7 +262,6 @@ arena_t *choose_arena_hard(void); #include "internal/jemalloc_chunk.h" #include "internal/jemalloc_huge.h" #include "internal/jemalloc_tcache.h" -#include "internal/jemalloc_trace.h" #include "internal/hash.h" #include "internal/prof.h" @@ -372,7 +369,6 @@ choose_arena(void) #include "internal/jemalloc_tcache.h" #include "internal/jemalloc_arena.h" -#include "internal/jemalloc_trace.h" #include "internal/hash.h" #include "internal/prof.h" diff --git a/jemalloc/src/internal/jemalloc_trace.h b/jemalloc/src/internal/jemalloc_trace.h deleted file mode 100644 index e474ed0..0000000 --- a/jemalloc/src/internal/jemalloc_trace.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifdef JEMALLOC_TRACE -/******************************************************************************/ -#ifdef JEMALLOC_H_TYPES - -#endif /* JEMALLOC_H_TYPES */ -/******************************************************************************/ -#ifdef JEMALLOC_H_STRUCTS - -#endif /* JEMALLOC_H_STRUCTS */ -/******************************************************************************/ -#ifdef JEMALLOC_H_EXTERNS - -extern bool opt_trace; - -void trace_malloc(const void *ptr, size_t size); -void trace_calloc(const void *ptr, size_t number, size_t size); -void trace_posix_memalign(const void *ptr, size_t alignment, size_t size); -void trace_realloc(const void *ptr, const void *old_ptr, size_t size, - size_t old_size); -void trace_free(const void *ptr, size_t size); -void trace_malloc_usable_size(size_t size, const void *ptr); -void trace_thread_exit(void); - -bool trace_boot(void); - -#endif /* JEMALLOC_H_EXTERNS */ -/******************************************************************************/ -#ifdef JEMALLOC_H_INLINES - -#endif /* JEMALLOC_H_INLINES */ -/******************************************************************************/ -#endif /* JEMALLOC_TRACE */ diff --git a/jemalloc/src/internal/mtrgraph_defs.h.in b/jemalloc/src/internal/mtrgraph_defs.h.in deleted file mode 100644 index 7a81e3c..0000000 --- a/jemalloc/src/internal/mtrgraph_defs.h.in +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef MTRGRAPH_DEFS_H_ -#define MTRGRAPH_DEFS_H_ - -/* Defined if __attribute__((...)) syntax is supported. */ -#undef JEMALLOC_HAVE_ATTR -#ifdef JEMALLOC_HAVE_ATTR -# define JEMALLOC_ATTR(s) __attribute__((s)) -#else -# define JEMALLOC_ATTR(s) -#endif - -#undef JEMALLOC_DEBUG - -#endif /* MTRGRAPH_DEFS_H_ */ diff --git a/jemalloc/src/internal/mtrplay_defs.h.in b/jemalloc/src/internal/mtrplay_defs.h.in deleted file mode 100644 index 8b62625..0000000 --- a/jemalloc/src/internal/mtrplay_defs.h.in +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef MTRPLAY_DEFS_H_ -#define MTRPLAY_DEFS_H_ - -/* Defined if __attribute__((...)) syntax is supported. */ -#undef JEMALLOC_HAVE_ATTR -#ifdef JEMALLOC_HAVE_ATTR -# define JEMALLOC_ATTR(s) __attribute__((s)) -#else -# define JEMALLOC_ATTR(s) -#endif - -#undef JEMALLOC_DEBUG - -#endif /* MTRPLAY_DEFS_H_ */ diff --git a/jemalloc/src/jemalloc.c b/jemalloc/src/jemalloc.c index 813f50b..dfff742 100644 --- a/jemalloc/src/jemalloc.c +++ b/jemalloc/src/jemalloc.c @@ -581,14 +581,6 @@ MALLOC_OUT: opt_lg_cspace_max) opt_lg_qspace_max++; break; -#ifdef JEMALLOC_TRACE - case 't': - opt_trace = false; - break; - case 'T': - opt_trace = true; - break; -#endif #ifdef JEMALLOC_PROF case 'u': opt_prof_udump = false; @@ -650,14 +642,6 @@ MALLOC_OUT: return (true); } -#ifdef JEMALLOC_TRACE - if (opt_trace) { - if (trace_boot()) { - malloc_mutex_unlock(&init_lock); - return (true); - } - } -#endif if (opt_stats_print) { /* Print statistics at exit. */ if (atexit(stats_print_atexit) != 0) { @@ -914,10 +898,6 @@ RETURN: if (opt_prof && ret != NULL) prof_malloc(ret, cnt); #endif -#ifdef JEMALLOC_TRACE - if (opt_trace) - trace_malloc(ret, size); -#endif return (ret); } @@ -1005,10 +985,6 @@ RETURN: if (opt_prof && result != NULL) prof_malloc(result, cnt); #endif -#ifdef JEMALLOC_TRACE - if (opt_trace) - trace_posix_memalign(result, alignment, size); -#endif return (ret); } @@ -1079,10 +1055,6 @@ RETURN: if (opt_prof && ret != NULL) prof_malloc(ret, cnt); #endif -#ifdef JEMALLOC_TRACE - if (opt_trace) - trace_calloc(ret, num, size); -#endif return (ret); } @@ -1091,28 +1063,11 @@ void * JEMALLOC_P(realloc)(void *ptr, size_t size) { void *ret; -#if (defined(JEMALLOC_PROF) || defined(JEMALLOC_TRACE)) - size_t old_size; -#endif #ifdef JEMALLOC_PROF + size_t old_size; prof_thr_cnt_t *cnt, *old_cnt; #endif -/* - * Both profiling and tracing may need old_size, and the conditional logic for - * deciding whether to call isalloc() is messy. Define need_old_size here in - * order to avoid repeated nasty cpp conditional logic. - */ -#ifdef JEMALLOC_PROF -# ifdef JEMALLOC_TRACE -# define need_old_size opt_prof || opt_trace -# else -# define need_old_size opt_prof -# endif -#elif (defined(JEMALLOC_TRACE)) -# define need_old_size opt_trace -#endif - if (size == 0) { #ifdef JEMALLOC_SYSV if (opt_sysv == false) @@ -1121,24 +1076,20 @@ JEMALLOC_P(realloc)(void *ptr, size_t size) #ifdef JEMALLOC_SYSV else { if (ptr != NULL) { -#if (defined(JEMALLOC_PROF) || defined(JEMALLOC_TRACE)) - if (need_old_size) { +#ifdef JEMALLOC_PROF + if (opt_prof) { old_size = isalloc(ptr); -# ifdef JEMALLOC_PROF old_cnt = prof_cnt_get(ptr); cnt = NULL; -# endif } #endif idalloc(ptr); } -#if (defined(JEMALLOC_PROF) || defined(JEMALLOC_TRACE)) - else if (need_old_size) { +#ifdef JEMALLOC_PROF + else if (opt_prof) { old_size = 0; -# ifdef JEMALLOC_PROF old_cnt = NULL; cnt = NULL; -# endif } #endif ret = NULL; @@ -1151,16 +1102,14 @@ JEMALLOC_P(realloc)(void *ptr, size_t size) assert(malloc_initialized || malloc_initializer == pthread_self()); -#if (defined(JEMALLOC_PROF) || defined(JEMALLOC_TRACE)) - if (need_old_size) { +#ifdef JEMALLOC_PROF + if (opt_prof) { old_size = isalloc(ptr); -# ifdef JEMALLOC_PROF old_cnt = prof_cnt_get(ptr); if ((cnt = prof_alloc_prep()) == NULL) { ret = NULL; goto OOM; } -# endif } #endif @@ -1181,12 +1130,10 @@ OOM: errno = ENOMEM; } } else { -#if (defined(JEMALLOC_PROF) || defined(JEMALLOC_TRACE)) - if (need_old_size) { +#ifdef JEMALLOC_PROF + if (opt_prof) { old_size = 0; -# ifdef JEMALLOC_PROF old_cnt = NULL; -# endif } #endif if (malloc_init()) { @@ -1220,18 +1167,11 @@ OOM: #ifdef JEMALLOC_SYSV RETURN: #endif -#ifdef JEMALLOC_TRACE - if (opt_trace) - trace_realloc(ret, ptr, size, old_size); -#endif #ifdef JEMALLOC_PROF if (opt_prof) prof_realloc(ret, cnt, ptr, old_size, old_cnt); #endif return (ret); -#ifdef need_old_size -# undef need_old_size -#endif } JEMALLOC_ATTR(visibility("default")) @@ -1247,10 +1187,6 @@ JEMALLOC_P(free)(void *ptr) if (opt_prof) prof_free(ptr); #endif -#ifdef JEMALLOC_TRACE - if (opt_trace) - trace_free(ptr, isalloc(ptr)); -#endif idalloc(ptr); } } @@ -1272,10 +1208,6 @@ JEMALLOC_P(malloc_usable_size)(const void *ptr) assert(ptr != NULL); ret = isalloc(ptr); -#ifdef JEMALLOC_TRACE - if (opt_trace) - trace_malloc_usable_size(ret, ptr); -#endif return (ret); } diff --git a/jemalloc/src/jemalloc_arena.c b/jemalloc/src/jemalloc_arena.c index 585be3d..c3dc382 100644 --- a/jemalloc/src/jemalloc_arena.c +++ b/jemalloc/src/jemalloc_arena.c @@ -2023,49 +2023,6 @@ arena_new(arena_t *arena, unsigned ind) # endif #endif -#ifdef JEMALLOC_TRACE - if (opt_trace) { - /* "jemtr.<pid>.<arena>" */ - char buf[UMAX2S_BUFSIZE]; - char filename[6 + UMAX2S_BUFSIZE + 1 + UMAX2S_BUFSIZE + 1]; - char *s; - unsigned i, slen; - - arena->trace_buf_end = 0; - - i = 0; - - s = "jemtr."; - slen = strlen(s); - memcpy(&filename[i], s, slen); - i += slen; - - s = umax2s(getpid(), 10, buf); - slen = strlen(s); - memcpy(&filename[i], s, slen); - i += slen; - - s = "."; - slen = strlen(s); - memcpy(&filename[i], s, slen); - i += slen; - - s = umax2s(ind, 10, buf); - slen = strlen(s); - memcpy(&filename[i], s, slen); - i += slen; - - filename[i] = '\0'; - - arena->trace_fd = creat(filename, 0644); - if (arena->trace_fd == -1) { - malloc_write4("<jemalloc>", - ": creat(\"", filename, "\", 0644) failed\n"); - abort(); - } - } -#endif - #ifdef JEMALLOC_PROF arena->prof_accumbytes = 0; #endif diff --git a/jemalloc/src/jemalloc_ctl.c b/jemalloc/src/jemalloc_ctl.c index a68e78a..9775f72 100644 --- a/jemalloc/src/jemalloc_ctl.c +++ b/jemalloc/src/jemalloc_ctl.c @@ -48,7 +48,6 @@ CTL_PROTO(config_sysv) CTL_PROTO(config_tcache) CTL_PROTO(config_tiny) CTL_PROTO(config_tls) -CTL_PROTO(config_trace) CTL_PROTO(config_xmalloc) CTL_PROTO(opt_abort) #ifdef JEMALLOC_FILL @@ -75,9 +74,6 @@ CTL_PROTO(opt_prof_udump) CTL_PROTO(opt_prof_leak) #endif CTL_PROTO(opt_stats_print) -#ifdef JEMALLOC_TRACE -CTL_PROTO(opt_trace) -#endif CTL_PROTO(opt_lg_qspace_max) CTL_PROTO(opt_lg_cspace_max) CTL_PROTO(opt_lg_medium_max) @@ -214,7 +210,6 @@ static const ctl_node_t config_node[] = { {NAME("tcache"), CTL(config_tcache)}, {NAME("tiny"), CTL(config_tiny)}, {NAME("tls"), CTL(config_tls)}, - {NAME("trace"), CTL(config_trace)}, {NAME("xmalloc"), CTL(config_xmalloc)} }; @@ -244,9 +239,6 @@ static const ctl_node_t opt_node[] = { {NAME("prof_leak"), CTL(opt_prof_leak)}, #endif {NAME("stats_print"), CTL(opt_stats_print)}, -#ifdef JEMALLOC_TRACE - {NAME("trace"), CTL(opt_trace)}, -#endif {NAME("lg_qspace_max"), CTL(opt_lg_qspace_max)}, {NAME("lg_cspace_max"), CTL(opt_lg_cspace_max)}, {NAME("lg_medium_max"), CTL(opt_lg_medium_max)}, @@ -1046,12 +1038,6 @@ CTL_RO_TRUE_GEN(config_tls) CTL_RO_FALSE_GEN(config_tls) #endif -#ifdef JEMALLOC_TRACE -CTL_RO_TRUE_GEN(config_trace) -#else -CTL_RO_FALSE_GEN(config_trace) -#endif - #ifdef JEMALLOC_XMALLOC CTL_RO_TRUE_GEN(config_xmalloc) #else @@ -1085,9 +1071,6 @@ CTL_RO_GEN(opt_prof_udump, opt_prof_udump, bool) CTL_RO_GEN(opt_prof_leak, opt_prof_leak, bool) #endif CTL_RO_GEN(opt_stats_print, opt_stats_print, bool) -#ifdef JEMALLOC_TRACE -CTL_RO_GEN(opt_trace, opt_trace, bool) -#endif CTL_RO_GEN(opt_lg_qspace_max, opt_lg_qspace_max, size_t) CTL_RO_GEN(opt_lg_cspace_max, opt_lg_cspace_max, size_t) CTL_RO_GEN(opt_lg_medium_max, opt_lg_medium_max, size_t) diff --git a/jemalloc/src/jemalloc_defs.h.in b/jemalloc/src/jemalloc_defs.h.in index 942694f..4b4ea7d 100644 --- a/jemalloc/src/jemalloc_defs.h.in +++ b/jemalloc/src/jemalloc_defs.h.in @@ -45,9 +45,6 @@ /* JEMALLOC_STATS enables statistics calculation. */ #undef JEMALLOC_STATS -/* JEMALLOC_TRACE enables allocation tracing. */ -#undef JEMALLOC_TRACE - /* JEMALLOC_PROF enables allocation profiling. */ #undef JEMALLOC_PROF diff --git a/jemalloc/src/jemalloc_stats.c b/jemalloc/src/jemalloc_stats.c index 54aa103..7a7f111 100644 --- a/jemalloc/src/jemalloc_stats.c +++ b/jemalloc/src/jemalloc_stats.c @@ -440,8 +440,6 @@ stats_print(void (*write4)(void *, const char *, const char *, const char *, if ((err = mallctl("opt.overcommit", &bv, &bsz, NULL, 0)) == 0) write4(w4opaque, bv ? "O" : "o", "", "", ""); write4(w4opaque, "P", "", "", ""); - if ((err = mallctl("opt.trace", &bv, &bsz, NULL, 0)) == 0) - write4(w4opaque, bv ? "T" : "t", "", "", ""); if ((err = mallctl("opt.prof_udump", &bv, &bsz, NULL, 0)) == 0) write4(w4opaque, bv ? "U" : "u", "", "", ""); if ((err = mallctl("opt.sysv", &bv, &bsz, NULL, 0)) == 0) diff --git a/jemalloc/src/jemalloc_trace.c b/jemalloc/src/jemalloc_trace.c deleted file mode 100644 index a2146f5..0000000 --- a/jemalloc/src/jemalloc_trace.c +++ /dev/null @@ -1,281 +0,0 @@ -#define JEMALLOC_TRACE_C_ -#include "internal/jemalloc_internal.h" -#ifdef JEMALLOC_TRACE -/******************************************************************************/ -/* Data. */ - -bool opt_trace = false; - -static malloc_mutex_t trace_mtx; -static unsigned trace_next_tid = 1; - -static unsigned __thread trace_tid - JEMALLOC_ATTR(tls_model("initial-exec")); -/* Used to cause trace_cleanup() to be called. */ -static pthread_key_t trace_tsd; - -/******************************************************************************/ -/* Function prototypes for non-inline static functions. */ - -static arena_t *trace_arena(const void *ptr); -static void trace_flush(arena_t *arena); -static void trace_write(arena_t *arena, const char *s); -static unsigned trace_get_tid(void); -static void trace_thread_cleanup(void *arg); -static void malloc_trace_flush_all(void); - -/******************************************************************************/ - -static arena_t * -trace_arena(const void *ptr) -{ - arena_t *arena; - arena_chunk_t *chunk; - - chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); - if ((void *)chunk == ptr) - arena = arenas[0]; - else - arena = chunk->arena; - - return (arena); -} - -static void -trace_flush(arena_t *arena) -{ - ssize_t err; - - err = write(arena->trace_fd, arena->trace_buf, arena->trace_buf_end); - if (err == -1) { - malloc_write4("<jemalloc>", - ": write() failed during trace flush", "\n", ""); - if (opt_abort) - abort(); - } - arena->trace_buf_end = 0; -} - -static void -trace_write(arena_t *arena, const char *s) -{ - unsigned i, slen, n; - - i = 0; - slen = strlen(s); - while (i < slen) { - /* Flush the trace buffer if it is full. */ - if (arena->trace_buf_end == TRACE_BUF_SIZE) - trace_flush(arena); - - if (arena->trace_buf_end + slen <= TRACE_BUF_SIZE) { - /* Finish writing. */ - n = slen - i; - } else { - /* Write as much of s as will fit. */ - n = TRACE_BUF_SIZE - arena->trace_buf_end; - } - memcpy(&arena->trace_buf[arena->trace_buf_end], &s[i], n); - arena->trace_buf_end += n; - i += n; - } -} - -static unsigned -trace_get_tid(void) -{ - unsigned ret = trace_tid; - - if (ret == 0) { - malloc_mutex_lock(&trace_mtx); - trace_tid = trace_next_tid; - trace_next_tid++; - malloc_mutex_unlock(&trace_mtx); - ret = trace_tid; - - /* - * Set trace_tsd to non-zero so that the cleanup function will - * be called upon thread exit. - */ - pthread_setspecific(trace_tsd, (void *)ret); - } - - return (ret); -} - -static void -malloc_trace_flush_all(void) -{ - unsigned i; - - for (i = 0; i < narenas; i++) { - if (arenas[i] != NULL) { - malloc_mutex_lock(&arenas[i]->lock); - trace_flush(arenas[i]); - malloc_mutex_unlock(&arenas[i]->lock); - } - } -} - -void -trace_malloc(const void *ptr, size_t size) -{ - char buf[UMAX2S_BUFSIZE]; - arena_t *arena = trace_arena(ptr); - - malloc_mutex_lock(&arena->lock); - - trace_write(arena, umax2s(trace_get_tid(), 10, buf)); - trace_write(arena, " m 0x"); - trace_write(arena, umax2s((uintptr_t)ptr, 16, buf)); - trace_write(arena, " "); - trace_write(arena, umax2s(size, 10, buf)); - trace_write(arena, "\n"); - - malloc_mutex_unlock(&arena->lock); -} - -void -trace_calloc(const void *ptr, size_t number, size_t size) -{ - char buf[UMAX2S_BUFSIZE]; - arena_t *arena = trace_arena(ptr); - - malloc_mutex_lock(&arena->lock); - - trace_write(arena, umax2s(trace_get_tid(), 10, buf)); - trace_write(arena, " c 0x"); - trace_write(arena, umax2s((uintptr_t)ptr, 16, buf)); - trace_write(arena, " "); - trace_write(arena, umax2s(number, 10, buf)); - trace_write(arena, " "); - trace_write(arena, umax2s(size, 10, buf)); - trace_write(arena, "\n"); - - malloc_mutex_unlock(&arena->lock); -} - -void -trace_posix_memalign(const void *ptr, size_t alignment, size_t size) -{ - char buf[UMAX2S_BUFSIZE]; - arena_t *arena = trace_arena(ptr); - - malloc_mutex_lock(&arena->lock); - - trace_write(arena, umax2s(trace_get_tid(), 10, buf)); - trace_write(arena, " a 0x"); - trace_write(arena, umax2s((uintptr_t)ptr, 16, buf)); - trace_write(arena, " "); - trace_write(arena, umax2s(alignment, 10, buf)); - trace_write(arena, " "); - trace_write(arena, umax2s(size, 10, buf)); - trace_write(arena, "\n"); - - malloc_mutex_unlock(&arena->lock); -} - -void -trace_realloc(const void *ptr, const void *old_ptr, size_t size, - size_t old_size) -{ - char buf[UMAX2S_BUFSIZE]; - arena_t *arena = trace_arena(ptr); - - malloc_mutex_lock(&arena->lock); - - trace_write(arena, umax2s(trace_get_tid(), 10, buf)); - trace_write(arena, " r 0x"); - trace_write(arena, umax2s((uintptr_t)ptr, 16, buf)); - trace_write(arena, " 0x"); - trace_write(arena, umax2s((uintptr_t)old_ptr, 16, buf)); - trace_write(arena, " "); - trace_write(arena, umax2s(size, 10, buf)); - trace_write(arena, " "); - trace_write(arena, umax2s(old_size, 10, buf)); - trace_write(arena, "\n"); - - malloc_mutex_unlock(&arena->lock); -} - -void -trace_free(const void *ptr, size_t size) -{ - char buf[UMAX2S_BUFSIZE]; - arena_t *arena = trace_arena(ptr); - - malloc_mutex_lock(&arena->lock); - - trace_write(arena, umax2s(trace_get_tid(), 10, buf)); - trace_write(arena, " f 0x"); - trace_write(arena, umax2s((uintptr_t)ptr, 16, buf)); - trace_write(arena, " "); - trace_write(arena, umax2s(isalloc(ptr), 10, buf)); - trace_write(arena, "\n"); - - malloc_mutex_unlock(&arena->lock); -} - -void -trace_malloc_usable_size(size_t size, const void *ptr) -{ - char buf[UMAX2S_BUFSIZE]; - arena_t *arena = trace_arena(ptr); - - malloc_mutex_lock(&arena->lock); - - trace_write(arena, umax2s(trace_get_tid(), 10, buf)); - trace_write(arena, " s "); - trace_write(arena, umax2s(size, 10, buf)); - trace_write(arena, " 0x"); - trace_write(arena, umax2s((uintptr_t)ptr, 16, buf)); - trace_write(arena, "\n"); - - malloc_mutex_unlock(&arena->lock); -} - -void -trace_thread_exit(void) -{ - char buf[UMAX2S_BUFSIZE]; - arena_t *arena = choose_arena(); - - malloc_mutex_lock(&arena->lock); - - trace_write(arena, umax2s(trace_get_tid(), 10, buf)); - trace_write(arena, " x\n"); - - malloc_mutex_unlock(&arena->lock); -} - -static void -trace_thread_cleanup(void *arg) -{ - - trace_thread_exit(); -} - -bool -trace_boot(void) -{ - - if (malloc_mutex_init(&trace_mtx)) - return (true); - - /* Flush trace buffers at exit. */ - if (atexit(malloc_trace_flush_all) != 0) { - malloc_write4("<jemalloc>", ": Error in atexit()\n", "", ""); - if (opt_abort) - abort(); - } - /* Receive thread exit notifications. */ - if (pthread_key_create(&trace_tsd, trace_thread_cleanup) != 0) { - malloc_write4("<jemalloc>", - ": Error in pthread_key_create()\n", "", ""); - abort(); - } - - return (false); -} -/******************************************************************************/ -#endif /* JEMALLOC_TRACE */ diff --git a/jemalloc/src/jemtr2mtr.c b/jemalloc/src/jemtr2mtr.c deleted file mode 100644 index 3361ae1..0000000 --- a/jemalloc/src/jemtr2mtr.c +++ /dev/null @@ -1,12 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -int -main(int argc, char **argv) -{ - // XXX Parse a jemtr trace and convert it to a mtr trace. - fprintf(stderr, "XXX Not implemented\n"); - abort(); - - return 0; -} diff --git a/jemalloc/src/mtrgraph.c b/jemalloc/src/mtrgraph.c deleted file mode 100644 index c5f9dd3..0000000 --- a/jemalloc/src/mtrgraph.c +++ /dev/null @@ -1,1054 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <stdbool.h> -#include <stdint.h> -#include <inttypes.h> -#include <limits.h> -#include <errno.h> -#include <string.h> - -#include <gd.h> -#include <gdfontt.h> -#include <gdfonts.h> -#include <gdfontmb.h> -#include <gdfontl.h> -#include <gdfontg.h> - -#include "internal/mtrgraph_defs.h" -#ifndef JEMALLOC_DEBUG -# define NDEBUG -#endif -#include <assert.h> -#include "internal/rb.h" - -typedef struct -{ - // malloc: {0, size, addr} - // realloc: {oldAddr, size, addr} - // free: {oldAddr, 0, 0} - uintptr_t oldAddr; - size_t size; - uintptr_t addr; -} TraceRecord; - -typedef struct -{ - TraceRecord *trace; - uint64_t traceLen; -} Trace; - -typedef struct AllocationCacheRecordStruct AllocationCacheRecord; -struct AllocationCacheRecordStruct -{ - rb_node(AllocationCacheRecord) link; - - uint64_t addr; - uint64_t size; -}; -typedef rb_tree(AllocationCacheRecord) AllocationCache; - -int -cacheComp(AllocationCacheRecord *a, AllocationCacheRecord *b) -{ - if (a->addr < b->addr) - { - return -1; - } - else if (a->addr > b->addr) - { - return 1; - } - else - { - return 0; - } -} - -rb_wrap(static JEMALLOC_ATTR(unused), cache_tree_, AllocationCache, - AllocationCacheRecord, link, cacheComp) - -// Parse utrace records. Following are prototypical examples of each type of -// record: -// -// <jemalloc>:utrace: 31532 malloc_init() -// <jemalloc>:utrace: 31532 0x800b01000 = malloc(34816) -// <jemalloc>:utrace: 31532 free(0x800b0a400) -// <jemalloc>:utrace: 31532 0x800b35230 = realloc(0x800b35230, 45) -Trace * -parseInput(FILE *infile, uint64_t pastEvent) -{ - Trace *rVal; - uint64_t maxLen; - int result; - char buf[128]; - unsigned pid; - void *addr, *oldAddr; - size_t size; - - rVal = (Trace *) malloc(sizeof(Trace)); - if (rVal == NULL) - { - fprintf(stderr, "mtrgraph: Error in malloc()\n"); - goto RETURN; - } - - maxLen = 1024; - rVal->trace = (TraceRecord *) malloc(maxLen * sizeof(TraceRecord)); - if (rVal->trace == NULL) - { - fprintf(stderr, "mtrgraph: Error in malloc()\n"); - free(rVal); - rVal = NULL; - goto RETURN; - } - - rVal->traceLen = 0; - while (rVal->traceLen < pastEvent) - { - // Expand trace buffer, if necessary. - if (rVal->traceLen == maxLen) - { - TraceRecord *t; - - maxLen *= 2; - t = (TraceRecord *) realloc(rVal->trace, - maxLen * sizeof(TraceRecord)); - if (t == NULL) - { - fprintf(stderr, "mtrgraph: Error in realloc()\n"); - free(rVal->trace); - free(rVal); - rVal = NULL; - goto RETURN; - } - rVal->trace = t; - } - - // Get a line of input. - { - int c; - unsigned i; - - for (i = 0; i < sizeof(buf) - 1; i++) - { - c = fgetc(infile); - switch (c) - { - case EOF: - { - goto RETURN; - } - case '\n': - { - buf[i] = '\0'; - goto OUT; - } - default: - { - buf[i] = c; - break; - } - } - } - OUT:; - } - - // realloc? - result = sscanf(buf, "<jemalloc>:utrace: %u %p = realloc(%p, %zu)", - &pid, &addr, &oldAddr, &size); - if (result == 4) - { - rVal->trace[rVal->traceLen].oldAddr = (uintptr_t) oldAddr; - rVal->trace[rVal->traceLen].size = size; - rVal->trace[rVal->traceLen].addr = (uintptr_t) addr; - - rVal->traceLen++; - continue; - } - - // malloc? - result = sscanf(buf, "<jemalloc>:utrace: %u %p = malloc(%zu)", - &pid, &addr, &size); - if (result == 3) - { - rVal->trace[rVal->traceLen].oldAddr = (uintptr_t) NULL; - rVal->trace[rVal->traceLen].size = size; - rVal->trace[rVal->traceLen].addr = (uintptr_t) addr; - - rVal->traceLen++; - continue; - } - - // free? - result = sscanf(buf, "<jemalloc>:utrace: %u free(%p)", - &pid, &oldAddr); - if (result == 2) - { - rVal->trace[rVal->traceLen].oldAddr = (uintptr_t) oldAddr; - rVal->trace[rVal->traceLen].size = 0; - rVal->trace[rVal->traceLen].addr = (uintptr_t) NULL; - - rVal->traceLen++; - continue; - } - - // malloc_init? - result = sscanf(buf, "<jemalloc>:utrace: %u malloc_init()", - &pid); - if (result == 1) - { - continue; - } - - goto ERROR; - } - -RETURN: - return rVal; -ERROR: - fprintf(stderr, "mtrgraph: Error reading record %"PRIu64" of input\n", - rVal->traceLen + 1); - free(rVal->trace); - free(rVal); - rVal = NULL; - goto RETURN; -} - -bool -genOutput(FILE *outfile, const char *fileType, bool legend, - unsigned long xSize, unsigned long ySize, - Trace *trace, uint64_t minAddr, uint64_t maxAddr, uint64_t quantum, - uint64_t minEvent, uint64_t pastEvent, uint64_t stride) -{ - bool rVal; - gdImagePtr img; -#define NCOLORS 256 - int white, black; - int colors[NCOLORS]; - uint64_t i, buckets[ySize]; - unsigned long bucket; - unsigned long x = 0; - AllocationCache cache; - AllocationCacheRecord *rec, key; - gdFontPtr font; - - img = gdImageCreate((int) xSize, (int) ySize); - - black = gdImageColorAllocate(img, 0, 0, 0); - white = gdImageColorAllocate(img, 255, 255, 255); - // Create a palette of colors. - for (i = 0; i < NCOLORS; i++) - { - colors[i] = gdImageColorAllocate(img, 255 - i, i, - (i < NCOLORS / 2) ? i * 2 : (NCOLORS - i - 1) * 2); - } - - // Set up fonts. - font = gdFontGetLarge(); - - memset(buckets, 0, ySize * sizeof(uint64_t)); - - cache_tree_new(&cache); - - for (i = 0; i < trace->traceLen; i++) - { - if (trace->trace[i].oldAddr == 0 && trace->trace[i].addr != 0) - { - // malloc. - - // Update buckets. - if (trace->trace[i].size > 0) - { - uint64_t size, offset; - - size = trace->trace[i].size; - bucket = (trace->trace[i].addr - minAddr) / quantum; - offset = (trace->trace[i].addr - minAddr) % quantum; - - if (bucket < ySize) - { - if (quantum - offset >= size) - { - buckets[bucket] += size; - size = 0; - } - else - { - buckets[bucket] += (quantum - offset); - size -= (quantum - offset); - } - bucket++; - - while (bucket < ySize && size > 0) - { - if (size > quantum) - { - buckets[bucket] += quantum; - size -= quantum; - } - else - { - buckets[bucket] += size; - size = 0; - } - bucket++; - } - } - } - - // Cache size of allocation. - rec = (AllocationCacheRecord *) - malloc(sizeof(AllocationCacheRecord)); - if (rec == NULL) - { - fprintf(stderr, "mtrgraph: Error in malloc()\n"); - rVal = true; - goto RETURN; - } - - rec->addr = trace->trace[i].addr; - rec->size = trace->trace[i].size; - - cache_tree_insert(&cache, rec); - } - else if (trace->trace[i].oldAddr != 0 && trace->trace[i].addr != 0) - { - // realloc. - - // Remove old allocation from cache. - key.addr = trace->trace[i].oldAddr; - rec = cache_tree_search(&cache, &key); - if (rec == NULL) - { - fprintf(stderr, - "mtrgraph: Trace record %"PRIu64 - " realloc()s unknown object 0x%"PRIx64"\n", - i, (uint64_t)trace->trace[i].oldAddr); - rVal = true; - goto RETURN; - } - - // Update buckets (dealloc). - if (rec->size > 0) - { - uint64_t size, offset; - - size = rec->size; - bucket = (trace->trace[i].oldAddr - minAddr) / quantum; - offset = (trace->trace[i].oldAddr - minAddr) % quantum; - - if (bucket < ySize) - { - if (quantum - offset >= size) - { - buckets[bucket] -= size; - size = 0; - } - else - { - buckets[bucket] -= (quantum - offset); - size -= (quantum - offset); - } - bucket++; - - while (bucket < ySize && size > 0) - { - if (size > quantum) - { - buckets[bucket] -= quantum; - size -= quantum; - } - else - { - buckets[bucket] -= size; - size = 0; - } - bucket++; - } - } - } - - // Update buckets (alloc). - if (trace->trace[i].size > 0) - { - uint64_t size, offset; - - size = trace->trace[i].size; - bucket = (trace->trace[i].addr - minAddr) / quantum; - offset = (trace->trace[i].addr - minAddr) % quantum; - - if (bucket < ySize) - { - if (quantum - offset >= size) - { - buckets[bucket] += size; - size = 0; - } - else - { - buckets[bucket] += (quantum - offset); - size -= (quantum - offset); - } - bucket++; - - while (bucket < ySize && size > 0) - { - if (size > quantum) - { - buckets[bucket] += quantum; - size -= quantum; - } - else - { - buckets[bucket] += size; - size = 0; - } - bucket++; - } - } - } - - // Cache size of allocation. - cache_tree_remove(&cache, rec); - rec->addr = trace->trace[i].addr; - rec->size = trace->trace[i].size; - cache_tree_insert(&cache, rec); - } - else if (trace->trace[i].oldAddr != 0 - && trace->trace[i].size == 0 - && trace->trace[i].addr == 0) - { - // free. - - // Remove old allocation from cache. - key.addr = trace->trace[i].oldAddr; - rec = cache_tree_search(&cache, &key); - if (rec == NULL) - { - fprintf(stderr, - "mtrgraph: Trace record %"PRIu64 - " free()s unknown object 0x%"PRIx64"\n", - i, (uint64_t)trace->trace[i].oldAddr); - rVal = true; - goto RETURN; - } - - // Update buckets. - if (rec->size > 0) - { - uint64_t size, offset; - - size = rec->size; - bucket = (trace->trace[i].oldAddr - minAddr) / quantum; - offset = (trace->trace[i].oldAddr - minAddr) % quantum; - - if (bucket < ySize) - { - if (quantum - offset >= size) - { - buckets[bucket] -= size; - size = 0; - } - else - { - buckets[bucket] -= (quantum - offset); - size -= (quantum - offset); - } - bucket++; - - while (bucket < ySize && size > 0) - { - if (size > quantum) - { - buckets[bucket] -= quantum; - size -= quantum; - } - else - { - buckets[bucket] -= size; - size = 0; - } - bucket++; - } - } - } - - cache_tree_remove(&cache, rec); - free(rec); - } - - // Plot buckets in graph. - if (i >= minEvent && i < pastEvent && ((i - minEvent) % stride) == 0) - { - unsigned long j; - int color; - - for (j = 0; j < ySize; j++) - { - if (buckets[j] > 0) - { - color = (NCOLORS * ((double) buckets[j] / (double) quantum)) - - 1; - gdImageSetPixel(img, x, ySize - j, colors[color]); - } - } - x++; - } - } - - // Print graph legend. - if (legend) - { -#define BUFLEN 256 - char buf[BUFLEN]; - - // Create color palette legend. - if (ySize >= NCOLORS) - { - for (i = 0; i < NCOLORS; i++) - { - gdImageLine(img, 0, NCOLORS - i - 1, 31, NCOLORS - i - 1, - colors[i]); - } - gdImageLine(img, 0, 0, 31, 0, white); - gdImageLine(img, 0, 256, 31, 256, white); - gdImageLine(img, 0, 0, 0, 256, white); - gdImageLine(img, 31, 0, 31, 256, white); - - gdImageString(img, font, 40, 0, (unsigned char *)"Full bucket", - white); - gdImageString(img, font, 40, 240, - (unsigned char *)"Fragmented bucket", white); - } - - snprintf(buf, BUFLEN, - "Horizontal: Events [%"PRIu64"..%"PRIu64"), stride %"PRIu64"", - minEvent, pastEvent, stride); - gdImageString(img, font, 200, 0, (unsigned char *)buf, white); - - snprintf(buf, BUFLEN, - "Vertical: Addresses [0x%016"PRIx64"..0x%016"PRIx64 - "), bucket size %"PRIu64"", minAddr, maxAddr, quantum); - gdImageString(img, font, 200, 20, (unsigned char *)buf, white); - - snprintf(buf, BUFLEN, - "Graph dimensions: %lu events by %lu buckets", - xSize, ySize); - gdImageString(img, font, 200, 40, (unsigned char *)buf, white); - } - - if (strcmp(fileType, "png") == 0) - { - gdImagePng(img, outfile); - } - else if (strcmp(fileType, "jpg") == 0) - { - gdImageJpeg(img, outfile, 100); - } - else if (strcmp(fileType, "gif") == 0) - { - gdImageGif(img, outfile); - } - else - { - // Unreachable code. - fprintf(stderr, "mtrgraph: Unsupported output file type '%s'\n", - fileType); - rVal = true; - goto RETURN; - } - - rVal = false; -RETURN: - // Clean up cache. - while (true) - { - rec = cache_tree_first(&cache); - if (rec == NULL) - { - break; - } - - cache_tree_remove(&cache, rec); - free(rec); - } - gdImageDestroy(img); - return rVal; -} - -void -usage(FILE *fp) -{ - fprintf(fp, "mtrgraph usage:\n"); - fprintf(fp, " mtrgraph -h\n"); - fprintf(fp, " mtrgraph [<options>]\n"); - fprintf(fp, "\n"); - fprintf(fp, " Option | Description\n"); - fprintf(fp, " -----------+------------------------------------------\n"); - fprintf(fp, " -h | Print usage and exit.\n"); - fprintf(fp, " -n | Don't actually generate a graph.\n"); - fprintf(fp, " -q | Don't print statistics to stdout.\n"); - fprintf(fp, " -l | Don't generate legend in graph.\n"); - fprintf(fp, " -f <file> | Input filename.\n"); - fprintf(fp, " -o <file> | Output filename.\n"); - fprintf(fp, " -t <type> | Output file type (png*, gif, jpg).\n"); - fprintf(fp, " -x <size> | Horizontal size of graph area, in pixels.\n"); - fprintf(fp, " -y <size> | Vertical size of graph area, in pixels.\n"); - fprintf(fp, " -m <addr> | Minimum address to graph.\n"); - fprintf(fp, " -M <addr> | Maximum address to graph.\n"); - fprintf(fp, " -e <time> | First event to graph.\n"); - fprintf(fp, " -E <time> | Last event to graph.\n"); - fprintf(fp, " -s <count> | Stride between event samples.\n"); -} - -int -main(int argc, char **argv) -{ - int rVal, c; - bool optNoAct = false; - bool optQuiet = false; - bool optLegend = true; - const char *optInfile = NULL; - const char *optOutfile = NULL; - const char *optFileType = "gif"; - unsigned long optXSize = 1280; - unsigned long optYSize = 1024; - uint64_t optMinAddr = 0ULL; - uint64_t optMaxAddr = ULLONG_MAX; - uint64_t optMinEvent = 0ULL; - uint64_t optPastEvent = ULLONG_MAX; - uint64_t optStride = 0ULL; - - FILE *infile, *outfile; - uint64_t minAddr, maxAddr; - Trace *trace = NULL; - uint64_t i, quantum, stride; - - opterr = 0; - optind = 1; - while ((c = getopt(argc, argv, -#ifdef _GNU_SOURCE - // Without this, glibc will permute unknown options to - // the end of the argument list. - "+" -#endif - "hnqlf:o:t:x:y:m:M:e:E:s:")) != -1) - { - switch (c) - { - case 'h': - { - if (argc != 2) - { - fprintf(stderr, - "mtrgraph: Incorrect number of arguments\n"); - usage(stderr); - rVal = 1; - goto RETURN; - } - usage(stdout); - rVal = 0; - goto RETURN; - } - case 'n': - { - optNoAct = true; - break; - } - case 'q': - { - optQuiet = true; - break; - } - case 'l': - { - optLegend = false; - break; - } - case 'f': - { - optInfile = optarg; - break; - } - case 'o': - { - optOutfile = optarg; - break; - } - case 't': - { - if (strcmp(optarg, "png") - && strcmp(optarg, "jpg") - && strcmp(optarg, "gif")) - { - fprintf(stderr, "mtrgraph: Invalid option '-%c %s'\n", - c, optarg); - usage(stderr); - rVal = 1; - goto RETURN; - } - optFileType = optarg; - break; - } - case 'x': - { - errno = 0; - optXSize = strtoul(optarg, NULL, 0); - if (optXSize == ULONG_MAX && errno != 0) - { - fprintf(stderr, "mtrgraph: Error in option '-%c %s': %s\n", - c, optarg, strerror(errno)); - usage(stderr); - rVal = 1; - goto RETURN; - } - else if (optXSize == 0) - { - fprintf(stderr, "mtrgraph: Invalid option '-%c %s'\n", - c, optarg); - usage(stderr); - rVal = 1; - goto RETURN; - } - break; - } - case 'y': - { - errno = 0; - optYSize = strtoul(optarg, NULL, 0); - if (optYSize == ULONG_MAX && errno != 0) - { - fprintf(stderr, "mtrgraph: Error in option '-%c %s': %s\n", - c, optarg, strerror(errno)); - usage(stderr); - rVal = 1; - goto RETURN; - } - else if (optYSize == 0) - { - fprintf(stderr, "mtrgraph: Invalid option '-%c %s'\n", - c, optarg); - usage(stderr); - rVal = 1; - goto RETURN; - } - break; - } - case 'm': - { - errno = 0; - optMinAddr = strtoull(optarg, NULL, 0); - if (optMinAddr == ULLONG_MAX && errno != 0) - { - fprintf(stderr, "mtrgraph: Error in option '-%c %s': %s\n", - c, optarg, strerror(errno)); - usage(stderr); - rVal = 1; - goto RETURN; - } - else if (optMinAddr == 0) - { - fprintf(stderr, "mtrgraph: Invalid option '-%c %s'\n", - c, optarg); - usage(stderr); - rVal = 1; - goto RETURN; - } - break; - } - case 'M': - { - errno = 0; - optMaxAddr = strtoull(optarg, NULL, 0); - if (optMaxAddr == ULLONG_MAX && errno != 0) - { - fprintf(stderr, "mtrgraph: Error in option '-%c %s': %s\n", - c, optarg, strerror(errno)); - usage(stderr); - rVal = 1; - goto RETURN; - } - else if (optMaxAddr == 0) - { - fprintf(stderr, "mtrgraph: Invalid option '-%c %s'\n", - c, optarg); - usage(stderr); - rVal = 1; - goto RETURN; - } - break; - } - case 'e': - { - errno = 0; - optMinEvent = strtoull(optarg, NULL, 0); - if (optMinEvent == ULLONG_MAX && errno != 0) - { - fprintf(stderr, "mtrgraph: Error in option '-%c %s': %s\n", - c, optarg, strerror(errno)); - usage(stderr); - rVal = 1; - goto RETURN; - } - else if (optMinEvent == 0) - { - fprintf(stderr, "mtrgraph: Invalid option '-%c %s'\n", - c, optarg); - usage(stderr); - rVal = 1; - goto RETURN; - } - break; - } - case 'E': - { - errno = 0; - optPastEvent = strtoull(optarg, NULL, 0); - if (optPastEvent == ULLONG_MAX && errno != 0) - { - fprintf(stderr, "mtrgraph: Error in option '-%c %s': %s\n", - c, optarg, strerror(errno)); - usage(stderr); - rVal = 1; - goto RETURN; - } - else if (optPastEvent == 0) - { - fprintf(stderr, "mtrgraph: Invalid option '-%c %s'\n", - c, optarg); - usage(stderr); - rVal = 1; - goto RETURN; - } - break; - } - case 's': - { - errno = 0; - optStride = strtoull(optarg, NULL, 0); - if (optStride == ULLONG_MAX && errno != 0) - { - fprintf(stderr, "mtrgraph: Error in option '-%c %s': %s\n", - c, optarg, strerror(errno)); - usage(stderr); - rVal = 1; - goto RETURN; - } - else if (optStride == 0) - { - fprintf(stderr, "mtrgraph: Invalid option '-%c %s'\n", - c, optarg); - usage(stderr); - rVal = 1; - goto RETURN; - } - break; - } - default: - { - fprintf(stderr, "mtrgraph: Unrecognized option\n"); - usage(stderr); - rVal = 1; - goto RETURN; - } - } - } - - if (optInfile == NULL) - { - infile = stdin; - } - else - { - infile = fopen(optInfile, "r"); - if (infile == NULL) - { - fprintf(stderr, "mtrgraph: Invalid option '-f %s': %s\n", - optInfile, strerror(errno)); - usage(stderr); - rVal = 1; - goto RETURN; - } - } - - if (optNoAct == false) - { - if (optOutfile == NULL) - { - outfile = stdout; - } - else - { - outfile = fopen(optOutfile, "w"); - if (outfile == NULL) - { - fprintf(stderr, "mtrgraph: Invalid option '-o %s': %s\n", - optOutfile, strerror(errno)); - usage(stderr); - rVal = 1; - goto RETURN; - } - } - } - else - { - outfile = NULL; - } - - // Parse input trace. - if ((trace = parseInput(infile, optPastEvent)) == NULL) - { - rVal = 1; - goto RETURN; - } - - // Calculate graph parameters. - - // stride. - if (optMinEvent >= trace->traceLen || optPastEvent <= optMinEvent) - { - fprintf(stderr, "mtrgraph: No events in range [%"PRIu64"..%"PRIu64")\n", - optMinEvent, optPastEvent); - rVal = 1; - goto RETURN; - } - - if (optPastEvent >= trace->traceLen) - { - optPastEvent = trace->traceLen; - } - stride = (optPastEvent - optMinEvent) / optXSize; - if ((optPastEvent - optMinEvent) % optXSize != 0) - { - stride++; - } - if (stride < optStride) - { - stride = optStride; - } - - // Contract optXSize if there is unused space at the end of the graph. - { - unsigned long xSize; - - xSize = (optPastEvent - optMinEvent) / stride; - if ((optPastEvent - optMinEvent) % stride != 0) - { - xSize++; - } - - if (optXSize > xSize) - { - optXSize = xSize; - } - } - - // minAddr and maxAddr. - minAddr = ULLONG_MAX; - maxAddr = 0; - for (i = 0; i < trace->traceLen; i++) - { - if (i >= optMinEvent && i < optPastEvent) - { - if (trace->trace[i].addr != 0) - { - if (trace->trace[i].addr >= optMinAddr - && trace->trace[i].addr < minAddr) - { - minAddr = trace->trace[i].addr; - } - - if (trace->trace[i].addr < optMaxAddr - && trace->trace[i].addr + trace->trace[i].size > maxAddr) - { - if (trace->trace[i].addr + trace->trace[i].size - < optMaxAddr) - { - maxAddr = trace->trace[i].addr + trace->trace[i].size; - } - else - { - maxAddr = optMaxAddr; - } - } - } - } - } - if (minAddr == ULLONG_MAX || maxAddr == 0 || minAddr >= maxAddr) - { - fprintf(stderr, - "mtrgraph: No events in specified address range " - "0x%016"PRIx64"..0x%016"PRIx64"\n", - minAddr, maxAddr); - rVal = 1; - goto RETURN; - } - - // quantum. - for (quantum = 1; - ((double) (maxAddr - minAddr) / (double) quantum) > (double) optYSize; - quantum <<= 1) - { - // Do nothing. - } - - // Expand minAddr and maxAddr to the nearest quantum boundaries. - minAddr -= (minAddr % quantum); - if (maxAddr % quantum != 0) - { - maxAddr -= (maxAddr % quantum); - maxAddr += quantum; - } - if (minAddr >= maxAddr) - { - fprintf(stderr, - "mtrgraph: No events in specified address range " - "0x%016"PRIx64"..0x%016"PRIx64"\n", - minAddr, maxAddr); - rVal = 1; - goto RETURN; - } - - if (optQuiet == false) - { - fprintf(stderr, "%"PRIu64" records read\n", trace->traceLen); - fprintf(stderr, "Graph addresses [0x%016"PRIx64"..0x%016"PRIx64")\n", - minAddr, maxAddr); - fprintf(stderr, "Graph events [%"PRIu64"..%"PRIu64")\n", - optMinEvent, optPastEvent); - fprintf(stderr, "Quantum: %"PRIu64"\n", quantum); - fprintf(stderr, "Stride: %"PRIu64"\n", stride); - fprintf(stderr, "Graph size: %lu x %lu\n", optXSize, optYSize); - } - - // Contract optYSize if there is unused image space. - if (optYSize > (maxAddr - minAddr) / quantum) - { - optYSize = (maxAddr - minAddr) / quantum; - } - - // Generate graph. - if (optNoAct == false) - { - if (genOutput(outfile, optFileType, optLegend, optXSize, optYSize, - trace, minAddr, maxAddr, quantum, - optMinEvent, optPastEvent, stride)) - { - rVal = 1; - goto RETURN; - } - } - - rVal = 0; -RETURN: - if (trace != NULL) - { - if (trace->trace != NULL) - { - free(trace->trace); - } - free(trace); - } - return rVal; -} diff --git a/jemalloc/src/mtrplay.c b/jemalloc/src/mtrplay.c deleted file mode 100644 index 134930f..0000000 --- a/jemalloc/src/mtrplay.c +++ /dev/null @@ -1,225 +0,0 @@ -// Parse a malloc trace and simulate the allocation events. Records look like: -// -// <jemalloc>:utrace: 31532 malloc_init() -// <jemalloc>:utrace: 31532 0x800b01000 = malloc(34816) -// <jemalloc>:utrace: 31532 free(0x800b0a400) -// <jemalloc>:utrace: 31532 0x800b35230 = realloc(0x800b35230, 45) - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <inttypes.h> -#include <stdbool.h> -#include <string.h> -#include <unistd.h> - -#include <sys/mman.h> -#include <sys/types.h> - -#include "internal/mtrplay_defs.h" -#ifndef JEMALLOC_DEBUG -# define NDEBUG -#endif -#include <assert.h> -#include "internal/rb.h" - -typedef struct record_s record_t; -struct record_s { - rb_node(record_t) link; - uintptr_t tag; - void *obj; -}; -typedef rb_tree(record_t) record_tree_t; - -static int -record_comp(record_t *a, record_t *b) -{ - - if (a->tag < b->tag) - return (-1); - else if (a->tag == b->tag) - return (0); - else - return (1); -} - -rb_wrap(static JEMALLOC_ATTR(unused), record_tree_, record_tree_t, record_t, - link, record_comp) - -static record_t *rec_stack = NULL; - -static record_t * -record_alloc(void) -{ - record_t *ret; - - if (rec_stack == NULL) { - record_t *recs; - unsigned long i; -#define MMAP_SIZE (1024 * 1024 * 1024) - - recs = (record_t *)mmap(NULL, MMAP_SIZE, - PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); - if (recs == NULL) { - fprintf(stderr, "mtrplay: mmap() error (OOM)\n"); - exit(1); - } - - for (i = 0; i < MMAP_SIZE / sizeof(record_t); i++) { - recs[i].obj = (void *)rec_stack; - rec_stack = &recs[i]; - } - } - - ret = rec_stack; - rec_stack = (record_t *)ret->obj; - - return (ret); -} - -static void -record_dalloc(record_t *rec) -{ - - rec->obj = (void *)rec_stack; - rec_stack = rec; -} - -int -main(void) -{ - uint64_t line; - int result; - char fbuf[4096], lbuf[128]; - unsigned foff, flen, i; - unsigned pid; - void *addr, *oldaddr; - size_t size; - record_tree_t tree; - - record_tree_new(&tree); - - foff = flen = 0; - for (line = 1;; line++) { - if (line % 100000 == 0) - fprintf(stderr, "."); - - // Get a line of input. - for (i = 0; i < sizeof(lbuf) - 1; i++) { - // Refill the read buffer if necessary. We use read(2) - // instead of a higher level API in order to avoid - // internal allocation. - if (foff == flen) { - foff = 0; - flen = read(0, fbuf, sizeof(fbuf)); - if (flen <= 0) { - goto RETURN; - } - } - switch (fbuf[foff]) { - case '\n': { - lbuf[i] = '\0'; - foff++; - goto OUT; - } default: { - lbuf[i] = fbuf[foff]; - foff++; - break; - } - } - } - OUT:; - - // realloc? - result = sscanf(lbuf, - "<jemalloc>:utrace: %u %p = realloc(%p, %zu)", - &pid, &addr, &oldaddr, &size); - if (result == 4) { - record_t key, *rec; - void *p; - - key.tag = (uintptr_t)oldaddr; - rec = record_tree_search(&tree, &key); - if (rec == NULL) { - fprintf(stderr, - "mtrplay: Line %"PRIu64 - ": Record not found\n", line); - exit(1); - } - record_tree_remove(&tree, rec); - - p = realloc(rec->obj, size); - if (p == NULL) { - fprintf(stderr, "mtrplay: Line %"PRIu64 - ": OOM\n", line); - exit(1); - } - - rec->tag = (uintptr_t)addr; - rec->obj = p; - record_tree_insert(&tree, rec); - continue; - } - - // malloc? - result = sscanf(lbuf, "<jemalloc>:utrace: %u %p = malloc(%zu)", - &pid, &addr, &size); - if (result == 3) - { - void *p; - record_t *rec; - - rec = record_alloc(); - - p = malloc(size); - if (p == NULL) { - fprintf(stderr, "mtrplay: Line %"PRIu64 - ": OOM\n", line); - exit(1); - } - memset(p, 0, size); - - rec->tag = (uintptr_t)addr; - rec->obj = p; - record_tree_insert(&tree, rec); - continue; - } - - // free? - result = sscanf(lbuf, "<jemalloc>:utrace: %u free(%p)", - &pid, &oldaddr); - if (result == 2) - { - record_t key, *rec; - - key.tag = (uintptr_t)oldaddr; - rec = record_tree_search(&tree, &key); - if (rec == NULL) { - fprintf(stderr, - "mtrplay: Line %"PRIu64 - ": Record not found\n", line); - exit(1); - } - record_tree_remove(&tree, rec); - - free(rec->obj); - record_dalloc(rec); - continue; - } - - // malloc_init? - result = sscanf(lbuf, "<jemalloc>:utrace: %u malloc_init()", - &pid); - if (result == 1) - { - continue; - } - - fprintf(stderr, "mtrplay: Error reading line %"PRIu64 - " of input\n", line); - exit(1); - } - -RETURN: - return 0; -} |