aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/fncache.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-12-01 18:49:57 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2019-12-01 18:49:57 -0800
commitb7fcf31f7036895ca8fc3a30eefffab0e82f75f6 (patch)
treede2480af1cb8213dd32f56ab596759a76ec7bd57 /tools/perf/util/fncache.c
parentMerge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input (diff)
parentMerge tag 'perf-core-for-mingo-5.5-20191128' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent (diff)
downloadlinux-dev-b7fcf31f7036895ca8fc3a30eefffab0e82f75f6.tar.xz
linux-dev-b7fcf31f7036895ca8fc3a30eefffab0e82f75f6.zip
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Ingo Molnar: - Make /sys/devices/cpu/rdpmc based RDPMC enforcement more instantaneous - decoder: Update the Intel opcode map - Various tooling fixes, including a few late optimizations and cleanups. * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits) perf script: Fix invalid LBR/binary mismatch error perf script: Fix brstackinsn for AUXTRACE perf affinity: Add infrastructure to save/restore affinity perf pmu: Use file system cache to optimize sysfs access perf regs: Make perf_reg_name() return "unknown" instead of NULL perf diff: Use llabs() with 64-bit values perf diff: Use llabs() with 64-bit values perf/x86: Implement immediate enforcement of /sys/devices/cpu/rdpmc value of 0 perf tools: Allow to link with libbpf dynamicaly perf tests: Rename tests/map_groups.c to tests/maps.c perf tests: Rename thread-mg-share to thread-maps-share perf maps: Rename map_groups.h to maps.h perf maps: Rename 'mg' variables to 'maps' perf map_symbol: Rename ms->mg to ms->maps perf addr_location: Rename al->mg to al->maps perf thread: Rename thread->mg to thread->maps perf maps: Merge 'struct maps' with 'struct map_groups' x86/insn: perf tools: Add some more instructions to the new instructions test x86/insn: Add some more Intel instructions to the opcode map perf map: Remove unused functions ...
Diffstat (limited to 'tools/perf/util/fncache.c')
-rw-r--r--tools/perf/util/fncache.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/tools/perf/util/fncache.c b/tools/perf/util/fncache.c
new file mode 100644
index 000000000000..6225cbc52310
--- /dev/null
+++ b/tools/perf/util/fncache.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Manage a cache of file names' existence */
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <linux/list.h>
+#include "fncache.h"
+
+struct fncache {
+ struct hlist_node nd;
+ bool res;
+ char name[];
+};
+
+#define FNHSIZE 61
+
+static struct hlist_head fncache_hash[FNHSIZE];
+
+unsigned shash(const unsigned char *s)
+{
+ unsigned h = 0;
+ while (*s)
+ h = 65599 * h + *s++;
+ return h ^ (h >> 16);
+}
+
+static bool lookup_fncache(const char *name, bool *res)
+{
+ int h = shash((const unsigned char *)name) % FNHSIZE;
+ struct fncache *n;
+
+ hlist_for_each_entry(n, &fncache_hash[h], nd) {
+ if (!strcmp(n->name, name)) {
+ *res = n->res;
+ return true;
+ }
+ }
+ return false;
+}
+
+static void update_fncache(const char *name, bool res)
+{
+ struct fncache *n = malloc(sizeof(struct fncache) + strlen(name) + 1);
+ int h = shash((const unsigned char *)name) % FNHSIZE;
+
+ if (!n)
+ return;
+ strcpy(n->name, name);
+ n->res = res;
+ hlist_add_head(&n->nd, &fncache_hash[h]);
+}
+
+/* No LRU, only use when bounded in some other way. */
+bool file_available(const char *name)
+{
+ bool res;
+
+ if (lookup_fncache(name, &res))
+ return res;
+ res = access(name, R_OK) == 0;
+ update_fncache(name, res);
+ return res;
+}