]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: trace: don't call strlen() on the function's name
authorWilly Tarreau <w@1wt.eu>
Thu, 18 Sep 2025 06:26:50 +0000 (08:26 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 18 Sep 2025 06:31:57 +0000 (08:31 +0200)
Currently there's a small mistake in the way the trace function and
macros. The calling function name is known as a constant until the
macro and passed as-is to the __trace() function. That one needs to
know its length and will call ist() on it, resulting in a real call
to strlen() while that length was known before the call. Let's use
an ist instead of a const char* for __trace() and __trace_enabled()
so that we can now completely avoid calling strlen() during this
operation. This has significantly reduced the importance of
__trace_enabled() in perf top.

include/haproxy/trace.h
src/trace.c

index cab11299cfef4fde5fd7eb0934db3d554de63e69..75cde3b213a37001f5567c5edb80264871e201b3 100644 (file)
  * TRACE_ENABLED() reports whether or not trace is enabled for the current
  * source, level, mask and arguments.
  */
-#define TRACE_ENABLED(level, mask, args...) (_trace_enabled((level), (mask), TRACE_SOURCE, ist(TRC_LOC), __FUNCTION__, ##args))
+#define TRACE_ENABLED(level, mask, args...) (_trace_enabled((level), (mask), TRACE_SOURCE, ist(TRC_LOC), ist(__FUNCTION__), ##args))
 
 #define TRACE(msg, mask, args...)    \
-       _trace(TRACE_LEVEL,           (mask), TRACE_SOURCE, ist(TRC_LOC), NULL, TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
+       _trace(TRACE_LEVEL,           (mask), TRACE_SOURCE, ist(TRC_LOC), IST_NULL, TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
 
 #define TRACE_ERROR(msg, mask, args...)                        \
-       _trace(TRACE_LEVEL_ERROR,     (mask), TRACE_SOURCE, ist(TRC_LOC), NULL, TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
+       _trace(TRACE_LEVEL_ERROR,     (mask), TRACE_SOURCE, ist(TRC_LOC), IST_NULL, TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
 
 #define TRACE_USER(msg, mask, args...)                 \
-       _trace(TRACE_LEVEL_USER,      (mask), TRACE_SOURCE, ist(TRC_LOC), NULL, TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
+       _trace(TRACE_LEVEL_USER,      (mask), TRACE_SOURCE, ist(TRC_LOC), IST_NULL, TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
 
 #define TRACE_DATA(msg, mask, args...)  \
-       _trace(TRACE_LEVEL_DATA,   (mask), TRACE_SOURCE, ist(TRC_LOC), NULL, TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
+       _trace(TRACE_LEVEL_DATA,   (mask), TRACE_SOURCE, ist(TRC_LOC), IST_NULL, TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
 
 #define TRACE_PROTO(msg, mask, args...)    \
-       _trace(TRACE_LEVEL_PROTO,     (mask), TRACE_SOURCE, ist(TRC_LOC), NULL, TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
+       _trace(TRACE_LEVEL_PROTO,     (mask), TRACE_SOURCE, ist(TRC_LOC), IST_NULL, TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
 
 #define TRACE_STATE(msg, mask, args...)    \
-       _trace(TRACE_LEVEL_STATE,     (mask), TRACE_SOURCE, ist(TRC_LOC), NULL, TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
+       _trace(TRACE_LEVEL_STATE,     (mask), TRACE_SOURCE, ist(TRC_LOC), IST_NULL, TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
 
 #define TRACE_DEVEL(msg, mask, args...)    \
-       _trace(TRACE_LEVEL_DEVELOPER, (mask), TRACE_SOURCE, ist(TRC_LOC), __FUNCTION__, TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
+       _trace(TRACE_LEVEL_DEVELOPER, (mask), TRACE_SOURCE, ist(TRC_LOC), ist(__FUNCTION__), TRC_5ARGS(0,##args,0,0,0,0,0), ist(msg))
 
 #define TRACE_ENTER(mask, args...)  \
-       _trace(TRACE_LEVEL_DEVELOPER, (mask), TRACE_SOURCE, ist(TRC_LOC), __FUNCTION__, TRC_5ARGS(0,##args,0,0,0,0,0), ist("entering"))
+       _trace(TRACE_LEVEL_DEVELOPER, (mask), TRACE_SOURCE, ist(TRC_LOC), ist(__FUNCTION__), TRC_5ARGS(0,##args,0,0,0,0,0), ist("entering"))
 
 #define TRACE_LEAVE(mask, args...)  \
-       _trace(TRACE_LEVEL_DEVELOPER, (mask), TRACE_SOURCE, ist(TRC_LOC), __FUNCTION__, TRC_5ARGS(0,##args,0,0,0,0,0), ist("leaving"))
+       _trace(TRACE_LEVEL_DEVELOPER, (mask), TRACE_SOURCE, ist(TRC_LOC), ist(__FUNCTION__), TRC_5ARGS(0,##args,0,0,0,0,0), ist("leaving"))
 
 #define TRACE_POINT(mask, args...)  \
-       _trace(TRACE_LEVEL_DEVELOPER, (mask), TRACE_SOURCE, ist(TRC_LOC), __FUNCTION__, TRC_5ARGS(0,##args,0,0,0,0,0), ist("in"))
+       _trace(TRACE_LEVEL_DEVELOPER, (mask), TRACE_SOURCE, ist(TRC_LOC), ist(__FUNCTION__), TRC_5ARGS(0,##args,0,0,0,0,0), ist("in"))
 
 /* This produces a printf-like trace at level <level> for event mask <mask> and
  * trace arguments <a1..a4>. All args mandatory, but may be zero. No output
                        _msg_len = snprintf(_msg, sizeof(_msg), (fmt), ##args); \
                        if (_msg_len >= sizeof(_msg))                           \
                                _msg_len = sizeof(_msg) - 1;                    \
-                       _trace((level), (mask), TRACE_SOURCE,   \
-                              trc_loc, func, a1, a2, a3, a4,                   \
+                       _trace((level), (mask), TRACE_SOURCE,                   \
+                              trc_loc, ist(func), a1, a2, a3, a4,              \
                               &trace_no_cb, ist2(_msg, _msg_len));             \
                }                                                               \
        } while (0)
@@ -172,12 +172,12 @@ extern struct list trace_sources;
 extern THREAD_LOCAL struct buffer trace_buf;
 
 int __trace_enabled(enum trace_level level, uint64_t mask, struct trace_source *src,
-                   const struct ist where, const char *func,
+                   const struct ist where, const struct ist ist_func,
                    const void *a1, const void *a2, const void *a3, const void *a4,
                    const void **plockptr);
 
 void __trace(enum trace_level level, uint64_t mask, struct trace_source *src,
-             const struct ist where, const char *func,
+             const struct ist where, const struct ist ist_func,
              const void *a1, const void *a2, const void *a3, const void *a4,
              void (*cb)(enum trace_level level, uint64_t mask, const struct trace_source *src,
                         const struct ist where, const struct ist func,
index 0952ed29bee21e55bef65690e901f27e5250fb2c..ecf4e654b6fbabd3a807d2c11567fd9989f511e7 100644 (file)
@@ -87,7 +87,7 @@ static inline const void *trace_pick_arg(uint32_t arg_def, const void *a1, const
  * and check if the result is >0.
  */
 int __trace_enabled(enum trace_level level, uint64_t mask, struct trace_source *src,
-                   const struct ist where, const char *func,
+                   const struct ist where, const struct ist ist_func,
                    const void *a1, const void *a2, const void *a3, const void *a4,
                    const void **plockptr)
 {
@@ -252,7 +252,7 @@ int __trace_enabled(enum trace_level level, uint64_t mask, struct trace_source *
 
 /* write a message for the given trace source */
 void __trace(enum trace_level level, uint64_t mask, struct trace_source *src,
-             const struct ist where, const char *func,
+             const struct ist where, const struct ist ist_func,
              const void *a1, const void *a2, const void *a3, const void *a4,
              void (*cb)(enum trace_level level, uint64_t mask, const struct trace_source *src,
                         const struct ist where, const struct ist func,
@@ -260,14 +260,13 @@ void __trace(enum trace_level level, uint64_t mask, struct trace_source *src,
              const struct ist msg)
 {
        const void *lockon_ptr;
-       struct ist ist_func = ist(func);
        char tnum[4];
        struct ist line[12];
        int words = 0;
        int ret;
 
        lockon_ptr = NULL;
-       ret = __trace_enabled(level, mask, src, where, func, a1, a2, a3, a4, &lockon_ptr);
+       ret = __trace_enabled(level, mask, src, where, ist_func, a1, a2, a3, a4, &lockon_ptr);
        if (lockon_ptr)
                HA_ATOMIC_STORE(&src->lockon_ptr, lockon_ptr);