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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.