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
next prev parent 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
-- strict thread matches above, loose matches on Subject: below --
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 \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).