[DTrace-devel] [PATCH 5/7] htab reduction: modules
Nick Alcock
nick.alcock at oracle.com
Tue Oct 5 06:38:49 PDT 2021
This one is nice and simple, just the same as all the others.
Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
---
libdtrace/dt_impl.h | 6 ++--
libdtrace/dt_module.c | 65 ++++++++++++++++++++++++++-----------------
libdtrace/dt_open.c | 9 ++----
3 files changed, 45 insertions(+), 35 deletions(-)
diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index a500917f9c1c..8601e4c50554 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -113,7 +113,8 @@ typedef struct dt_module {
char dm_name[DTRACE_MODNAMELEN]; /* string name of module */
char dm_file[PATH_MAX]; /* file path of module */
uint_t dm_flags; /* module flags (see below) */
- struct dt_module *dm_next; /* pointer to next module in hash chain */
+ struct dt_hentry dm_he; /* htab links */
+
dtrace_addr_range_t *dm_text_addrs; /* text addresses, sorted */
size_t dm_text_addrs_size; /* number of entries */
@@ -279,8 +280,7 @@ struct dtrace_hdl {
uint_t dt_maxreclen; /* largest record size across programs */
uint_t dt_maxlvaralloc; /* largest lvar alloc across pcbs */
dt_list_t dt_modlist; /* linked list of dt_module_t's */
- dt_module_t **dt_mods; /* hash table of dt_module_t's */
- uint_t dt_modbuckets; /* number of module hash buckets */
+ dt_htab_t *dt_mods; /* hash table of dt_module_t's */
uint_t dt_nmods; /* number of modules in hash and list */
Elf *dt_ctf_elf; /* ELF handle to the special 'ctf' module */
ctf_archive_t *dt_ctfa; /* ctf archive for the entire kernel tree */
diff --git a/libdtrace/dt_module.c b/libdtrace/dt_module.c
index 14013d929ad1..899324ff225c 100644
--- a/libdtrace/dt_module.c
+++ b/libdtrace/dt_module.c
@@ -40,6 +40,22 @@ dt_module_shuffle_to_start(dtrace_hdl_t *dtp, const char *name);
static void
dt_kern_module_find_ctf(dtrace_hdl_t *dtp, dt_module_t *dmp);
+static uint32_t
+dt_module_hval(const dt_module_t *mod)
+{
+ return str2hval(mod->dm_name, 0);
+}
+
+static int
+dt_module_cmp(const dt_module_t *p,
+ const dt_module_t *q)
+{
+ return strcmp(p->dm_name, q->dm_name);
+}
+
+DEFINE_HE_STD_LINK_FUNCS(dt_module, dt_module_t, dm_he)
+DEFINE_HTAB_STD_OPS(dt_module)
+
/*
* Symbol table management for userspace modules, via ELF parsing.
*/
@@ -96,21 +112,25 @@ dt_module_symgelf64(const Elf64_Sym *src, GElf_Sym *dst)
dt_module_t *
dt_module_create(dtrace_hdl_t *dtp, const char *name)
{
- uint_t h = str2hval(name, 0) % dtp->dt_modbuckets;
dt_module_t *dmp;
- for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next)
- if (strcmp(dmp->dm_name, name) == 0)
- return dmp;
+ if (!dtp->dt_mods &&
+ ((dtp->dt_mods = dt_htab_create(dtp, &dt_module_htab_ops)) == NULL))
+ return NULL;
+
+ if ((dmp = dt_module_lookup_by_name(dtp, name)) != NULL)
+ return dmp;
if ((dmp = malloc(sizeof(dt_module_t))) == NULL)
return NULL; /* caller must handle allocation failure */
memset(dmp, 0, sizeof(dt_module_t));
strlcpy(dmp->dm_name, name, sizeof(dmp->dm_name));
+ if (dt_htab_insert(dtp->dt_mods, dmp) < 0) {
+ free(dmp);
+ return NULL;
+ }
dt_list_append(&dtp->dt_modlist, dmp);
- dmp->dm_next = dtp->dt_mods[h];
- dtp->dt_mods[h] = dmp;
dtp->dt_nmods++;
if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64)
@@ -124,8 +144,13 @@ dt_module_create(dtrace_hdl_t *dtp, const char *name)
dt_module_t *
dt_module_lookup_by_name(dtrace_hdl_t *dtp, const char *name)
{
- uint_t h = str2hval(name, 0) % dtp->dt_modbuckets;
- dt_module_t *dmp;
+ dt_module_t skel;
+
+ if (strlen(name) > (DTRACE_MODNAMELEN - 1))
+ return NULL;
+
+ if (!dtp->dt_mods)
+ return NULL; /* no modules yet */
/* 'genunix' is an alias for 'vmlinux'. */
@@ -133,11 +158,8 @@ dt_module_lookup_by_name(dtrace_hdl_t *dtp, const char *name)
name = "vmlinux";
}
- for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next)
- if (strcmp(dmp->dm_name, name) == 0)
- return dmp;
-
- return NULL;
+ strcpy(skel.dm_name, name);
+ return dt_htab_lookup(dtp->dt_mods, &skel);
}
/*ARGSUSED*/
@@ -671,25 +693,16 @@ dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
void
dt_module_destroy(dtrace_hdl_t *dtp, dt_module_t *dmp)
{
- uint_t h = str2hval(dmp->dm_name, 0) % dtp->dt_modbuckets;
- dt_module_t *scan_dmp;
- dt_module_t *prev_dmp = NULL;
-
dt_list_delete(&dtp->dt_modlist, dmp);
assert(dtp->dt_nmods != 0);
dtp->dt_nmods--;
-
- for (scan_dmp = dtp->dt_mods[h]; (scan_dmp != NULL) && (scan_dmp != dmp);
- scan_dmp = scan_dmp->dm_next) {
- prev_dmp = scan_dmp;
- }
- if (prev_dmp == NULL)
- dtp->dt_mods[h] = dmp->dm_next;
- else
- prev_dmp->dm_next = dmp->dm_next;
+ dt_htab_delete(dtp->dt_mods, dmp);
dt_module_unload(dtp, dmp);
free(dmp);
+
+ if (dtp->dt_nmods == 0)
+ dt_htab_destroy(dtp, dtp->dt_mods);
}
/*
diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
index 5df8fef14b9b..4e9c886c494c 100644
--- a/libdtrace/dt_open.c
+++ b/libdtrace/dt_open.c
@@ -734,8 +734,6 @@ dt_vopen(int version, int flags, int *errp,
dtp->dt_ddefs_fd = -1;
dtp->dt_stdout_fd = -1;
dtp->dt_poll_fd = -1;
- dtp->dt_modbuckets = _dtrace_strbuckets;
- dtp->dt_mods = calloc(dtp->dt_modbuckets, sizeof(dt_module_t *));
dt_proc_hash_create(dtp);
dtp->dt_proc_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
dtp->dt_nextepid = 1;
@@ -768,9 +766,9 @@ dt_vopen(int version, int flags, int *errp,
if (dt_str2kver(dtp->dt_uts.release, &dtp->dt_kernver) < 0)
return set_open_errno(dtp, errp, EDT_VERSINVAL);
- if (dtp->dt_mods == NULL || dtp->dt_procs == NULL ||
- dtp->dt_ld_path == NULL || dtp->dt_cpp_path == NULL ||
- dtp->dt_cpp_argv == NULL || dtp->dt_sysslice == NULL)
+ if (dtp->dt_procs == NULL || dtp->dt_ld_path == NULL ||
+ dtp->dt_cpp_path == NULL || dtp->dt_cpp_argv == NULL ||
+ dtp->dt_sysslice == NULL)
return set_open_errno(dtp, errp, EDT_NOMEM);
for (i = 0; i < DTRACEOPT_MAX; i++)
@@ -1281,7 +1279,6 @@ dtrace_close(dtrace_hdl_t *dtp)
pthread_mutex_destroy(&dtp->dt_sprintf_lock);
elf_end(dtp->dt_ctf_elf);
- free(dtp->dt_mods);
free(dtp->dt_module_path);
free(dtp->dt_strtab);
free(dtp);
--
2.33.0.256.gb827f06fa9
More information about the DTrace-devel
mailing list