]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tools: resolve main() only once in resolve_sym_name()
authorWilly Tarreau <w@1wt.eu>
Thu, 21 Nov 2024 13:14:49 +0000 (14:14 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 21 Nov 2024 18:58:06 +0000 (19:58 +0100)
resolv_sym_name() calls dladdr(main) for each symbol in order to compare
the first address with other symbols. But this is pointless and quite
expensive in outputs to "show profiling" for example. Let's just keep a
local copy and have a variable indicating if the resolution is needed/
in progress/done to save the value for subsequent calls.

src/tools.c

index 224c5df97a5500d85b338f42723d6d9520302e08..968b324858e8b37e17d6598cb9fc6f0430f8dc3e 100644 (file)
@@ -5536,7 +5536,9 @@ const void *resolve_sym_name(struct buffer *buf, const char *pfx, const void *ad
        };
 
 #if (defined(__ELF__) && !defined(__linux__)) || defined(USE_DL)
-       Dl_info dli, dli_main;
+       static Dl_info dli_main;
+       static int dli_main_done; // 0 = not resolved, 1 = resolve in progress, 2 = done
+       Dl_info dli;
        size_t size;
        const char *fname, *p;
 #endif
@@ -5561,8 +5563,21 @@ const void *resolve_sym_name(struct buffer *buf, const char *pfx, const void *ad
         * that contains the main function. The name is picked between last '/'
         * and first following '.'.
         */
-       if (!dladdr(main, &dli_main))
-               dli_main.dli_fbase = NULL;
+
+       /* let's check main only once, no need to do it all the time */
+
+       i = HA_ATOMIC_LOAD(&dli_main_done);
+       while (i < 2) {
+               i = 0;
+               if (HA_ATOMIC_CAS(&dli_main_done, &i, 1)) {
+                       /* we're the first ones, resolve it */
+                       if (!dladdr(main, &dli_main))
+                               dli_main.dli_fbase = NULL;
+                       HA_ATOMIC_STORE(&dli_main_done, 2); // done
+                       break;
+               }
+               ha_thread_relax();
+       }
 
        if (dli_main.dli_fbase != dli.dli_fbase) {
                fname = dli.dli_fname;