lttng-dev.lists.lttng.org archive mirror
 help / color / mirror / Atom feed
From: Norbert Lange via lttng-dev <lttng-dev@lists.lttng.org>
To: lttng-dev@lists.lttng.org
Subject: [lttng-dev] [PATCH lttng-ust] Improve tracef/tracelog to use the stack for small strings
Date: Thu, 20 May 2021 14:18:07 +0200	[thread overview]
Message-ID: <20210520121807.55428-2-nolange79@gmail.com> (raw)
In-Reply-To: <20210520121807.55428-1-nolange79@gmail.com>

Support two common cases, one being that the resulting message is
small enough to fit into a on-stack buffer.
The seconds being the common 'printf("%s", "Message")' scheme.

Unfortunately, iterating a va_list is destructive,
so it has to be copied before calling vprintf.
This will result in the function never becoming inlined,
thus the helper function was manually "inlined".

Signed-off-by: Norbert Lange <nolange79@gmail.com>
---
 src/common/tracer.h          |  2 +
 src/lib/lttng-ust/tracef.c   | 83 ++++++++++++++++++++++++---------
 src/lib/lttng-ust/tracelog.c | 90 ++++++++++++++++++++++++------------
 3 files changed, 122 insertions(+), 53 deletions(-)

diff --git a/src/common/tracer.h b/src/common/tracer.h
index 2affd6ab..8e18c9b5 100644
--- a/src/common/tracer.h
+++ b/src/common/tracer.h
@@ -26,6 +26,8 @@
 #define LTTNG_RFLAG_EXTENDED		RING_BUFFER_RFLAG_END
 #define LTTNG_RFLAG_END			(LTTNG_RFLAG_EXTENDED << 1)
 
+#define LTTNG_TRACE_PRINTF_BUFSIZE	512
+
 /*
  * LTTng client type enumeration. Used by the consumer to map the
  * callbacks from its own address space.
diff --git a/src/lib/lttng-ust/tracef.c b/src/lib/lttng-ust/tracef.c
index c05c7811..21af5b9e 100644
--- a/src/lib/lttng-ust/tracef.c
+++ b/src/lib/lttng-ust/tracef.c
@@ -7,6 +7,7 @@
 #define _LGPL_SOURCE
 #include <stdio.h>
 #include "common/macros.h"
+#include "common/tracer.h"
 
 /* The tracepoint definition is public, but the provider definition is hidden. */
 #define LTTNG_UST_TRACEPOINT_PROVIDER_HIDDEN_DEFINITION
@@ -15,30 +16,40 @@
 #define LTTNG_UST_TRACEPOINT_DEFINE
 #include "lttng-ust-tracef-provider.h"
 
-static inline
-void lttng_ust___vtracef(const char *fmt, va_list ap)
-	__attribute__((always_inline, format(printf, 1, 0)));
-static inline
-void lttng_ust___vtracef(const char *fmt, va_list ap)
-{
-	char *msg;
-	const int len = vasprintf(&msg, fmt, ap);
-
-	/* len does not include the final \0 */
-	if (len < 0)
-		goto end;
-	lttng_ust_tracepoint_cb_lttng_ust_tracef___event(msg, len,
-		LTTNG_UST_CALLER_IP());
-	free(msg);
-end:
-	return;
-}
-
 void lttng_ust__vtracef(const char *fmt, va_list ap)
 	__attribute__((format(printf, 1, 0)));
 void lttng_ust__vtracef(const char *fmt, va_list ap)
 {
-	lttng_ust___vtracef(fmt, ap);
+	char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE];
+	char *alloc_buff = NULL;
+	char *msg = local_buf;
+	size_t buflen = sizeof(local_buf);
+	int len = -1;
+
+	if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) {
+		msg = va_arg(ap, char *);
+		len = strlen(msg);
+	} else
+		do {
+			va_list ap2;
+
+			if (caa_unlikely(len >= sizeof(local_buf))) {
+				buflen = (size_t)(len) + 1U;
+				alloc_buff = (char *)malloc(buflen);
+				msg = alloc_buff;
+				if (!alloc_buff)
+					return;
+			}
+			va_copy(ap2, ap);
+			len = vsnprintf(msg, buflen, fmt, ap2);
+			va_end(ap2);
+		} while (caa_unlikely(len >= sizeof(local_buf) && !alloc_buff));
+
+	/* len does not include the final \0 */
+	if (caa_likely(len >= 0))
+		lttng_ust_tracepoint_cb_lttng_ust_tracef___event(msg, len,
+			LTTNG_UST_CALLER_IP());
+	free(alloc_buff);
 }
 
 void lttng_ust__tracef(const char *fmt, ...)
@@ -46,8 +57,34 @@ void lttng_ust__tracef(const char *fmt, ...)
 void lttng_ust__tracef(const char *fmt, ...)
 {
 	va_list ap;
+	char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE];
+	char *alloc_buff = NULL;
+	char *msg = local_buf;
+	size_t buflen = sizeof(local_buf);
+	int len = -1;
 
-	va_start(ap, fmt);
-	lttng_ust___vtracef(fmt, ap);
-	va_end(ap);
+	if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) {
+		va_start(ap, fmt);
+		msg = va_arg(ap, char *);
+		va_end(ap);
+		len = strlen(msg);
+	} else
+		do {
+			if (caa_unlikely(len >= sizeof(local_buf))) {
+				buflen = (size_t)(len) + 1U;
+				alloc_buff = (char *)malloc(buflen);
+				msg = alloc_buff;
+				if (!alloc_buff)
+					return;
+			}
+			va_start(ap, fmt);
+			len = vsnprintf(msg, buflen, fmt, ap);
+			va_end(ap);
+		} while (caa_unlikely(len >= sizeof(local_buf) && !alloc_buff));
+
+	/* len does not include the final \0 */
+	if (caa_likely(len >= 0))
+		lttng_ust_tracepoint_cb_lttng_ust_tracef___event(msg, len,
+			LTTNG_UST_CALLER_IP());
+	free(alloc_buff);
 }
diff --git a/src/lib/lttng-ust/tracelog.c b/src/lib/lttng-ust/tracelog.c
index b28c6c78..6889869c 100644
--- a/src/lib/lttng-ust/tracelog.c
+++ b/src/lib/lttng-ust/tracelog.c
@@ -7,6 +7,7 @@
 #define _LGPL_SOURCE
 #include <stdio.h>
 #include "common/macros.h"
+#include "common/tracer.h"
 
 /* The tracepoint definition is public, but the provider definition is hidden. */
 #define LTTNG_UST_TRACEPOINT_PROVIDER_HIDDEN_DEFINITION
@@ -31,44 +32,73 @@ extern void lttng_ust__tracelog_vprintf(tpcallback_t *callback,
 	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, va_list ap)
 	__attribute__ ((format(printf, 3, 0)));
 
-static inline
-void lttng_ust___tracelog_vprintf(tpcallback_t *callback,
-	const struct lttng_ust__tracelog_sourceinfo *source,
-	const char *fmt, va_list ap)
-	__attribute__((always_inline, format(printf, 3, 0)));
-
-
-static inline
-void lttng_ust___tracelog_vprintf(tpcallback_t *callback,
-	const struct lttng_ust__tracelog_sourceinfo *source,
-	const char *fmt, va_list ap)
-{
-	char *msg;
-	const int len = vasprintf(&msg, fmt, ap);
-
-	/* len does not include the final \0 */
-	if (len >= 0)
-		goto end;
-	(*callback)(source->file, source->line, source->func, msg, len,
-		LTTNG_UST_CALLER_IP());
-	free(msg);
-end:
-	return;
-}
-
-
 void lttng_ust__tracelog_printf(tpcallback_t *callback,
 	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, ...)
 {
 	va_list ap;
+	char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE];
+	char *alloc_buff = NULL;
+	char *msg = local_buf;
+	size_t buflen = sizeof(local_buf);
+	int len = -1;
+
+	if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) {
+		va_start(ap, fmt);
+		msg = va_arg(ap, char *);
+		va_end(ap);
+		len = strlen(msg);
+	} else
+		do {
+			if (caa_unlikely(len >= sizeof(local_buf))) {
+				buflen = (size_t)(len) + 1U;
+				alloc_buff = (char *)malloc(buflen);
+				msg = alloc_buff;
+				if (!alloc_buff)
+					return;
+			}
+			va_start(ap, fmt);
+			len = vsnprintf(msg, buflen, fmt, ap);
+			va_end(ap);
+		} while (caa_unlikely(len >= sizeof(local_buf) && !alloc_buff));
 
-	va_start(ap, fmt);
-	lttng_ust___tracelog_vprintf(callback, source, fmt, ap);
-	va_end(ap);
+	/* len does not include the final \0 */
+	if (caa_likely(len >= 0))
+		(*callback)(source->file, source->line, source->func, msg, len,
+			LTTNG_UST_CALLER_IP());
+	free(alloc_buff);
 }
 
 void lttng_ust__tracelog_vprintf(tpcallback_t *callback,
 	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, va_list ap)
 {
-	lttng_ust___tracelog_vprintf(callback, source, fmt, ap);
+	char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE];
+	char *alloc_buff = NULL;
+	char *msg = local_buf;
+	size_t buflen = sizeof(local_buf);
+	int len = -1;
+
+	if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) {
+		msg = va_arg(ap, char *);
+		len = strlen(msg);
+	} else
+		do {
+			va_list ap2;
+
+			if (caa_unlikely(len >= sizeof(local_buf))) {
+				buflen = (size_t)(len) + 1U;
+				alloc_buff = (char *)malloc(buflen);
+				msg = alloc_buff;
+				if (!alloc_buff)
+					return;
+			}
+			va_copy(ap2, ap);
+			len = vsnprintf(msg, buflen, fmt, ap2);
+			va_end(ap2);
+		} while (caa_unlikely(len >= sizeof(local_buf) && !alloc_buff));
+
+	/* len does not include the final \0 */
+	if (caa_likely(len >= 0))
+		(*callback)(source->file, source->line, source->func, msg, len,
+			LTTNG_UST_CALLER_IP());
+	free(alloc_buff);
 }
-- 
2.30.2

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

  reply	other threads:[~2021-05-20 12:18 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-20 12:18 [lttng-dev] [PATCH lttng-ust] Improve tracelog handling, reduce exported functions Norbert Lange via lttng-dev
2021-05-20 12:18 ` Norbert Lange via lttng-dev [this message]
2021-05-20 14:19 ` Mathieu Desnoyers via lttng-dev
2021-05-20 14:57   ` Norbert Lange via lttng-dev
2021-05-20 15:21     ` Mathieu Desnoyers via lttng-dev
2021-05-20 15:54       ` Norbert Lange via lttng-dev
2021-05-20 16:25         ` Mathieu Desnoyers via lttng-dev
2021-05-20 16:51           ` Norbert Lange via lttng-dev
2021-05-20 17:18             ` Mathieu Desnoyers via lttng-dev
2021-05-20 17:43               ` Norbert Lange via lttng-dev
2021-05-21 14:55                 ` Mathieu Desnoyers via lttng-dev
2021-05-25 13:32               ` Norbert Lange via lttng-dev
2021-05-25 13:44 [lttng-dev] [PATCH lttng-ust] Improve tracef/tracelog to use the stack for small strings Norbert Lange via lttng-dev
2021-05-25 13:47 ` Norbert Lange via lttng-dev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210520121807.55428-2-nolange79@gmail.com \
    --to=lttng-dev@lists.lttng.org \
    --cc=nolange79@gmail.com \
    --subject='Re: [lttng-dev] [PATCH lttng-ust] Improve tracef/tracelog to use the stack for small strings' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).