]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
eu-stacktrace WIP: add dwfltab resizing
authorSerhei Makarov <serhei@serhei.io>
Thu, 29 Aug 2024 14:46:50 +0000 (10:46 -0400)
committerSerhei Makarov <serhei@serhei.io>
Thu, 29 Aug 2024 18:18:00 +0000 (14:18 -0400)
src/Makefile.am
src/stacktrace.c

index 2541d2a01ead90493cbb891093b739ae6a7fd050..d4ec755add44f352aa9db676fbacd02ff75e6261 100644 (file)
@@ -82,7 +82,7 @@ strings_LDADD = $(libelf) $(libeu) $(argp_LDADD)
 ar_LDADD = libar.a $(libelf) $(libeu) $(argp_LDADD) $(obstack_LIBS)
 unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD)
 stack_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) $(demanglelib)
-stacktrace_LDADD = $(libelf) $(libdw) $(argp_LDADD)
+stacktrace_LDADD = $(libelf) $(libdw) $(libeu) $(argp_LDADD)
 elfcompress_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD)
 elfclassify_LDADD = $(libelf) $(libdw) $(libeu) $(argp_LDADD)
 
index 7c24ddb4b34923fb36b95962d137067f7b382df4..b96f900e922f573dfa75f645ca59afadb8d238aa 100644 (file)
@@ -658,17 +658,53 @@ typedef struct
 } dwfltab;
 
 /* TODO: Store in sui, update below functions. */
-/* XXX initial size must be a prime */
+/* XXX table size must be a prime */
 #define DWFLTAB_DEFAULT_SIZE 1021
+extern size_t next_prime (size_t); /* XXX from libeu.a lib/next_prime.c */
+dwfltab_ent *dwfltab_find(pid_t pid); /* forward decl */
+
 dwfltab default_table;
 
 /* XXX based on lib/dynamicsizehash.* *_init */
-void dwfltab_init(void)
+bool dwfltab_init(void)
 {
   dwfltab *htab = &default_table;
   htab->size = DWFLTAB_DEFAULT_SIZE;
   htab->filled = 0;
   htab->table = calloc ((htab->size + 1), sizeof(htab->table[0]));
+  return (htab->table != NULL);
+}
+
+/* XXX based on lib/dynamicsizehash.* insert_entry_2 */
+bool dwfltab_resize(void)
+{
+  /* TODO: Also consider LRU eviction? */
+  dwfltab *htab = &default_table;
+  ssize_t old_size = htab->size;
+  dwfltab_ent *old_table = htab->table;
+  htab->size = next_prime (htab->size * 2);
+  htab->table = calloc ((htab->size + 1), sizeof(htab->table[0]));
+  if (htab->table == NULL)
+    {
+      htab->size = old_size;
+      htab->table = old_table;
+      return false;
+    }
+  htab->filled = 0;
+  /* Transfer the old entries to the new table. */
+  for (ssize_t idx = 1; idx <= old_size; ++idx)
+    if (old_table[idx].used)
+      {
+       dwfltab_ent *ent0 = &old_table[idx];
+       dwfltab_ent *ent1 = dwfltab_find(ent0->pid);
+       assert (ent1 != NULL);
+       memcpy (ent1, ent0, sizeof(dwfltab_ent));
+      }
+  free (old_table);
+  /* TODO: Control log level for this message: */
+  fprintf(stderr, "Resized Dwfl table from %ld to %ld, copied %ld entries\n",
+         old_size, htab->size, htab->filled);
+  return true;
 }
 
 /* XXX based on lib/dynamicsizehash.* *_find */
@@ -700,9 +736,9 @@ dwfltab_ent *dwfltab_find(pid_t pid)
  found:
   if (htab->table[idx].pid == 0)
     {
-      /* TODO: Implement resizing or LRU eviction? */
       if (100 * htab->filled > 90 * htab->size)
-       return NULL;
+       if (!dwfltab_resize())
+         return NULL;
       htab->table[idx].used = true;
       htab->table[idx].pid = pid;
       htab->filled += 1;
@@ -1462,7 +1498,8 @@ Utility is a work-in-progress, see README.eu-stacktrace in the source branch.")
     }
   else /* processing_mode == MODE_NAIVE */
     {
-      dwfltab_init();
+      if (!dwfltab_init())
+       error (EXIT_BAD, errno, N_("Could not initialize Dwfl table"));
       struct sysprof_unwind_info sui;
       sui.output_fd = output_fd;
       sui.reader = reader;
@@ -1482,7 +1519,7 @@ Utility is a work-in-progress, see README.eu-stacktrace in the source branch.")
          int total_samples = 0;
          int total_lost_samples = 0;
          fprintf(stderr, "\n=== final summary ===\n");
-         for (unsigned idx = 0; idx < DWFLTAB_DEFAULT_SIZE; idx++)
+         for (unsigned idx = 1; idx < default_table.size; idx++)
            {
              dwfltab *htab = &default_table;
              if (!htab->table[idx].used)