From 5ab3582ba148e9e5c7c86bd277b6bdbd56465bbd Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 19 Jun 2019 14:21:57 -0400 Subject: [PATCH] common: implement bt_common_g_string_append_printf g_string_append_printf() internally allocates a temporary buffer through use of vasnprintf for each call. This clearly appears at the top of perf report. Implement our own private bt_g_string_append_printf which operates directly on the GString buffer. See proof of memory allocation/free near the top of this perf report when converting a 400M LTTng trace to text (piped to /dev/null): 14.76% babeltrace2 libc-2.24.so [.] vfprintf 7.92% babeltrace2 [kernel.kallsyms] [k] vmacache_find 6.39% babeltrace2 libglib-2.0.so.0.5000.3 [.] g_string_insert_len 4.77% babeltrace2 babeltrace-plugin-ctf.so [.] bt_bfcr_start 4.23% babeltrace2 libc-2.24.so [.] _int_malloc 4.06% babeltrace2 libc-2.24.so [.] _IO_default_xsputn 3.60% babeltrace2 libc-2.24.so [.] strlen 3.60% babeltrace2 libc-2.24.so [.] __strchrnul 3.60% babeltrace2 libbabeltrace2.so.0.0.0 [.] bt_attributes_borrow_field_by_name 3.51% babeltrace2 libc-2.24.so [.] _int_free 2.88% babeltrace2 libc-2.24.so [.] __vasprintf_chk 2.88% babeltrace2 libc-2.24.so [.] _IO_str_init_static_internal 2.88% babeltrace2 libc-2.24.so [.] __strcmp_sse2_unaligned 2.16% babeltrace2 libc-2.24.so [.] malloc 2.16% babeltrace2 libc-2.24.so [.] __tzstring_len Signed-off-by: Mathieu Desnoyers Change-Id: I956305ac8891d244dbdab6a5b0dde82ecc960e25 Reviewed-on: https://review.lttng.org/c/babeltrace/+/1514 CI-Build: Philippe Proulx Reviewed-by: Philippe Proulx Tested-by: jenkins --- src/common/common.c | 32 ++++++++++++++++++++++++++++++++ src/common/common.h | 8 ++++++++ 2 files changed, 40 insertions(+) diff --git a/src/common/common.c b/src/common/common.c index d092768a..dacb5054 100644 --- a/src/common/common.c +++ b/src/common/common.c @@ -1822,3 +1822,35 @@ end: return ret; } #endif /* __MINGW32__ */ + +BT_HIDDEN +int bt_common_g_string_append_printf(GString *str, const char *fmt, ...) +{ + va_list ap; + gsize len, allocated_len, available_len; + int print_len; + + /* str->len excludes \0. */ + len = str->len; + /* Explicitly exclude \0. */ + allocated_len = str->allocated_len - 1; + available_len = allocated_len - len; + + str->len = allocated_len; + va_start(ap, fmt); + print_len = vsnprintf(str->str + len, available_len + 1, fmt, ap); + va_end(ap); + if (print_len < 0) { + return print_len; + } + if (G_UNLIKELY(available_len < print_len)) { + /* Resize. */ + g_string_set_size(str, len + print_len); + va_start(ap, fmt); + print_len = vsprintf(str->str + len, fmt, ap); + va_end(ap); + } else { + str->len = len + print_len; + } + return print_len; +} diff --git a/src/common/common.h b/src/common/common.h index b7245275..220ec61b 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -720,4 +721,11 @@ end: return ret; } +/* + * bt_g_string_append_printf cannot be inlined because it expects a + * variadic argument list. + */ +BT_HIDDEN +int bt_common_g_string_append_printf(GString *str, const char *fmt, ...); + #endif /* BABELTRACE_COMMON_INTERNAL_H */ -- 2.34.1